老师求助:点击上一张按钮,图片没有无缝过渡

来源:5-5 滑入滑出的第二种实现方式--头尾相连无缝滚动

我学习太差被关起来了

2020-11-25 03:13:56

# 具体遇到的问题


视频5-5,跟着老师敲代码到最后,点击上一张按钮,图片没有无缝过渡,显示空白如下。


http://img.mukewang.com/climg/5fbd58cb0a4089e507260493.jpg


点击下一张按钮则没有问题,图片能够无缝过渡。

我认为bug出在slider-slide-new.js上,应该是在Slider.prototype._slide函数。


# 粘贴全部相关代码,切记添加代码注释(请勿截图)


我的程序目录如下:

http://img.mukewang.com/climg/5fbd5932090ad2d402250447.jpg


HTML文件:slider-slide-new.html如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
   <head>
      <title>slider-slide-new</title>
      <meta charset="UTF-8">
      <meta name="renderer" content="webkit">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <link type="text/css" rel="stylesheet" href="../../reset.css">
        <link type="text/css" rel="stylesheet" href="../css/public.css">
      <style type="text/css">
         /*幻灯片*/
            .slider
            {
                overflow: hidden;
                position: relative;
                width: 728px;
                height: 504px;
            }
            /*索引点列表*/
            .slider__index
            {
                position: absolute;
                bottom: 25px;
                left: 50%;
                transform: translateX(-50%);
            }
            /*索引点*/
            .slider__index__dot
            {
                display: inline-block;
                margin: 0 8px;
                border-radius: 50%;
                width: 10px;
                height: 10px;
                background-color: #313A43;
                cursor: pointer;
            }
            /*当前索引点*/
            .slider__index__dot-on
            {
                box-shadow: 0 0 3px 3px rgba(111, 122, 133, .8);
                background-color: #F7F8F9;
            }
            /*按钮*/
            .ui-slider__btn
            {
                display: none;
                position: absolute;
                left: 0;
                top: 50%;
                transform: translateY(-50%);
                outline-style: none;
                width: 28px;
                height: 62px;
                line-height: 62px;
                font-size: 26px;
                text-align: center;
                color: #FFF;
                background-color: rgba(7, 17, 27, .5);
                font-family: simsun;
            }
            /*下一张按钮*/
            .ui-slider__btn.right
            {
                left: auto;
                right: 0;
            }
            .ui-slider__btn:hover
            {
                font-weight: bold;
            }
            /*淡入淡出切换*/
            .slider-fade .slider__container__item
            {
                display: none;
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
            }
            .slider-slide > .slider__container
            {
                position: absolute;
                top: 0;
                left: 0;
                width: 800%; /* 800米开外,一枪干掉鬼子! */
                height: 100%;
                background-color: #F35;
            }
            .slider-slide .slider__container__item
            { float: left; }
      </style>
   </head>
   <body>
      <!-- 幻灯片 -->
      <div id="focus__slider" class="slider slider-slide">
         <!-- 图片容器 -->
         <div class="slider__container">
            <div class="slider__container__item">
               <a href="##"><img src="../img/focus-slider/0.png" alt="慕课手机"></a>
            </div>
            <div class="slider__container__item">
               <a href="##"><img src="../img/focus-slider/1.png" alt="美的厨卫"></a>
            </div>
            <div class="slider__container__item">
               <a href="##"><img src="../img/focus-slider/2.png" alt="联想平板电脑"></a>
            </div>
            <div class="slider__container__item">
               <a href="##"><img src="../img/focus-slider/3.png" alt="耐克运动装备"></a>
            </div>
         </div>
            <!-- 索引点列表 -->
         <ol class="slider__index">
            <!-- 索引点 -->
            <li class="slider__index__dot hideText">0</li>
            <li class="slider__index__dot hideText">1</li>
            <li class="slider__index__dot hideText">2</li>
            <li class="slider__index__dot hideText">3</li>
         </ol>
            <!-- 上一张按钮 -->
         <button class="ui-slider__btn left" title="上一张">&lt;</button>
            <!-- 下一张按钮 -->
         <button class="ui-slider__btn right" title="下一张">&gt;</button>
      </div>
      <script type="text/javascript" src="../../jquery-1.12.4.min.js"></script>
      <script type="text/javascript" src="../js/transition.js"></script>
      <script type="text/javascript" src="../js/showHide.js"></script>
      <script type="text/javascript" src="../js/slider-slide.js"></script>
      <script type="text/javascript" src="../js/slider-slide-new.js"></script>
      <script type="text/javascript">
         $(document).ready(function()
            {
                let $slider = $("#focus__slider");
                $slider.slider({
                    css: true,
                    js: false,
                    animation: "slide", // "fade"为淡入淡出,"slide"为平移
                    iniIdx: 0, // 初始显示的图片
                    interval: 0, // 自动轮播的间隔时间
                    loop: true, // 是否首尾无缝过渡
                });
            });
      </script>
   </body>
</html>


reset.css如下:

/**  重置样式  **/
html, body, div, span,
h1, h2, h3, h4, h5, h6, p, pre,
a, address, big, cite, code,
em, img, ins, samp,
b, u, i, small, strike, strong, sub, sup, tt,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, thead, tbody, tfoot, tr, th, td,
article, aside, details,
figure, figcaption, footer, header, hgroup,
menu, nav, output, section, summary,
time, mark, audio, video
{
    margin: 0;
    padding: 0;
}
body
{
    font-family: "微软雅黑 Microsoft YaHei";
    font-size: 16px;
    color: #000;
    background-color: #FFF;
}
li
{list-style-type: none;}
a
{text-decoration-line: none;}


public.css如下:

/****************  公共样式  开始  ****************/
/*定宽样式*/
.wrap
{
    margin: 0 auto;
    width: 1200px;
    min-width: 1200px;
}

/*左浮动*/
.fl
{
    float: left;
}

/*右浮动*/
.fr
{
    float: right;
}

/*清除浮动*/
.clearfix::after
{
    display: block;
    content: " ";
    height: 0;
    clear: both;
    zoom: 1;
}

/*文字隐藏*/
.hideText
{
    text-indent: -9999px;
    overflow: hidden;
}

/*文字溢出省略号处理*/
.textOverflowEllipsis
{
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/*超链接样式*/
.link
{
    color: #4D555D;
}

/*超链接样式*/
.link:hover
{
    color: #F01414 !important;
    cursor: pointer;
}

@font-face
{
    font-family: "iconfont";
    src: url('../iconfont-sidebar-service/iconfont.eot?t=1477124206');
    src: url('../iconfont-sidebar-service/iconfont.eot?t=1477124206#iefix') format('embedded-opentype'),
    url('../iconfont-sidebar-service/iconfont.woff?t=1477124206') format('woff'),
    url('../iconfont-sidebar-service/iconfont.ttf?t=1477124206') format('truetype'),
    url('../iconfont-sidebar-service/iconfont.svg?t=1477124206#iconfont') format('svg');
}

.icon
{
    font-family: "iconfont" !important;
    font-size: 14px;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -webkit-text-stroke-width: 0.2px;
    -moz-osx-font-smoothing: grayscale;
}

/****************  公共样式  结束  ****************/


/****************  下拉菜单dropDown样式  开始  ****************/
/*下拉菜单*/
.dropDown
{
    position: relative;
}

/*切换文字*/
.dropDown-toggle
{
    position: relative;
    z-index: 1;
}

/*下拉箭头*/
.dropDown-arrow
{
    position: absolute;
}

/*下拉层,默认隐藏*/
.dropDown-layer
{
    display: none;
    overflow: hidden;
    position: absolute;
    z-index: 3;
}

/*下拉层左对齐*/
.dropDown-left
{
    left: 0;
    right: auto;
}

/*下拉层右对齐*/
.dropDown-right
{
    right: 0;
    left: auto;
}

/* 动画时间 */
.transition
{
    -o-transition: all .4s;
    -ms-transition: all .4s;
    -moz-transition: all .4s;
    -webkit-transition: all .4s;
    transition: all .4s;
}

.cartTransition
{
    -o-transition: all .1s;
    -ms-transition: all .1s;
    -moz-transition: all .1s;
    -webkit-transition: all .1s;
    transition: all .1s;
}

/*淡出效果*/
.fadeOut
{
    opacity: 0 !important;
    visibility: hidden !important;
}

/* 上下滑动隐藏 */
.slideUpDownCollapse
{
    height: 0 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* 左右滑动隐藏 */
.slideLeftRightCollapse
{
    width: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}

.dropDown-loading
{
    margin: 20px;
    width: 32px;
    height: 32px;
    background-image: url(../img/loading.gif);
    background-repeat: no-repeat;
}

/****************  下拉菜单dropDown样式  结束  ****************/


/****************  搜索框样式  开始  ****************/
/*搜索部分*/
.search
{
    position: relative;
    border: 1px solid #CFD2D5;
}

/*搜索输入框*/
.search-input
{
    outline-color: #DFDFDF;
    border-style: none;
    padding: 0 10px;
    width: 580px;
    height: 40px;
    line-height: 40px;
    font-size: 16px;
    background-color: #FFF;
}

/*搜索按钮*/
.search-button
{
    border-style: none;
    width: 72px;
    height: 40px;
    line-height: 36px;
    font-size: 15px;
    text-align: center;
    color: #FFF;
    background-color: #07111B;
    cursor: pointer;
}

/*搜索下拉层*/
.search-layer
{
    display: none;
    position: absolute;
    top: 100%;
    left: -1px;
    border: 1px solid #CFD2D5;
    width: 100%;
    background-color: #FFF;
}

/*搜索下拉层选项*/
.search-layer-item
{
    height: 24px;
    line-height: 24px;
    padding: 2px 8px;
    font-size: 15px;
    cursor: pointer;
}

.search-layer-item:hover
{
    background-color: #F3F5F7;
}

/****************  搜索框样式  结束  ****************/


/****************  focus区  开始  ****************/
.category
{
    position: relative;
    margin-top: -62px;
    width: 208px;
    font-size: 14px;
}

.category .dropDown
{
    position: static;
}

.category .dropDown-toggle
{
    height: 36px;
    line-height: 36px;
    padding-left: 16px;
    color: #FFF;
}

.category .dropDown-link
{
    color: #FFF;
}

.category .dropDown-arrow
{
    position: absolute;
    top: 0;
    right: 12px;
    font-family: 黑体;
    font-weight: bold;
}

.category-on .dropDown-toggle,
.category-on .dropDown-link
{
    color: #F01414;
}

.category-on .dropDown-toggle
{
    background-color: #FFF;
}

.category .dropDown-layer
{
    top: 54px;
    left: 100%;
    padding: 8px 0 30px 0;
    width: 744px;
    min-height: 472px;
    background-color: #FFF;
    box-shadow: 0 0 4px rgba(7, 27, 47, .2);
}

.category-details
{
    margin-top: 24px;
    width: 744px;
    line-height: 22px;
}

.category-details-title
{
    border-right: 1px solid #D9DDE1;
    padding-right: 16px;
    width: 84px;
    text-align: right;
    font-weight: bold;
    color: #07111B;
    cursor: pointer;
}

.category-details-item
{
    margin-bottom: 10px;
    padding-left: 15px;
    width: 592px;
    cursor: pointer;
}

.category-details-item:last-of-type
{
    margin-bottom: 0;
}

.category-details-item > .link
{
    display: inline-block;
    margin-right: 16px;
}

.focus__wrap__category__list .dropDown-loading
{
    margin: 230px auto;
    background-size: 45px;
    width: 45px;
    height: 45px;
}

/****************  focus区  结束  ****************/


transition.js如下:

// 解决transitionend事件的兼容性问题
// console.log(document.body.style.transition);

(function()
{
// transitionend事件名
let transitionendEvent =
{
transition: "transitionend",
MozTransition: "transitionend",
WebkitTransition: "webkitTransitionEnd",
OTransition: "oTransitionEnd otransitionend",
};

let transitionend = "",
isSupported = false;

for (let i in transitionendEvent)
{
if (document.body.style[i] !== undefined)
{
transitionend = transitionendEvent[i];
isSupported = true;
break;
}
}

// 全局变量MUTAO
window.MUTAO = window.MUTAO || {};

window.MUTAO =
{
transitionend: transitionend,
isSupported: isSupported,
};
})();


showHide.js如下:

(function($)
{
"use strict";

/**************************** module 1: start ****************************/
let silentAnimation =
{
// 初始化
init: function($ele)
{
init($ele);

console.log("silentAnimation init");
},

// 显示
show: function($ele)
{
show($ele, function()
{
// 调用jQuery的show方法
$ele.show();

// 触发自定义的shown事件,设置状态为shown
$ele.trigger("shown").data("status", "shown");
});

console.log("silentAnimation show");
},

// 隐藏
hide: function($ele)
{
hide($ele, function()
{
// 调用jQuery的hide方法
$ele.hide();

// 触发自定义的hidden事件,设置状态为hidden
$ele.trigger("hidden").data("status", "hidden");
});

console.log("silentAnimation hide");
},
};
/**************************** module 1: end ****************************/


/**************************** module 2: start ****************************/
let cssAnimation =
{
_init: function($ele, classname)
{
$ele.addClass("transition");

init($ele, function()
{
$ele.addClass(classname);
});
},

_show: function($ele, classname)
{
show($ele, function()
{
// 动画结束后,触发自定义的shown事件,设置状态为shown
$ele.off(window.MUTAO.transitionend).one(window.MUTAO.transitionend, function()
{
$ele.trigger("shown").data("status", "shown");
});

// 先显示
$ele.show();

// 后动画过渡
setTimeout(function()
{
$ele.removeClass(classname);
});
});
},

_hide: function($ele, classname)
{
hide($ele, function()
{
// 然后在动画结束后,隐藏
$ele.off(window.MUTAO.transitionend).one(window.MUTAO.transitionend, function()
{
$ele.hide();

// 触发自定义的hidden事件,设置状态为hidden
$ele.trigger("hidden").data("status", "hidden");
});

// 先动画过渡
$ele.addClass(classname);
});
},

// 淡入淡出效果
fade:
{
// 初始化
init: function($ele)
{
cssAnimation._init($ele, "fadeOut");

console.log("cssAnimation.fade init");
},

// 淡入
show: function($ele)
{
cssAnimation._show($ele, "fadeOut");

console.log("cssAnimation.fade show");
},

// 淡出
hide: function($ele)
{
cssAnimation._hide($ele, "fadeOut");

console.log("cssAnimation.fade hide");
},
},

// 上下滑动效果
slideUpDown:
{
// 初始化
init: function($ele)
{
// 设置高度
$ele.height($ele.height());

cssAnimation._init($ele, "slideUpDownCollapse");

console.log("cssAnimation.slideUpDown init");
},

// 上下滑动显示
show: function($ele)
{
cssAnimation._show($ele, "slideUpDownCollapse");

console.log("cssAnimation.slideUpDown show");
},

// 上下滑动隐藏
hide: function($ele)
{
cssAnimation._hide($ele, "slideUpDownCollapse");

console.log("cssAnimation.slideUpDown hide");
},
},

// 左右滑动效果
slideLeftRight:
{
// 初始化
init: function($ele)
{
// 设置宽度
$ele.width($ele.width());

cssAnimation._init($ele, "slideLeftRightCollapse");

console.log("cssAnimation.slideLeftRight init");
},

// 左右滑动显示
show: function($ele)
{
cssAnimation._show($ele, "slideLeftRightCollapse");

console.log("cssAnimation.slideLeftRight show");
},

// 左右滑动隐藏
hide: function($ele)
{
cssAnimation._hide($ele, "slideLeftRightCollapse");

console.log("cssAnimation.slideLeftRight hide");
},
},

// 淡入淡出+上下滑动效果
fadeSlideUpDown:
{
// 初始化
init: function($ele)
{
// 设置高度
$ele.height($ele.height());

cssAnimation._init($ele, "fadeOut slideUpDownCollapse");

console.log("cssAnimation.fadeSlideUpDown init");
},

// 上下滑动显示
show: function($ele)
{
cssAnimation._show($ele, "fadeOut slideUpDownCollapse");

console.log("cssAnimation.fadeSlideUpDown show");
},

// 上下滑动隐藏
hide: function($ele)
{
cssAnimation._hide($ele, "fadeOut slideUpDownCollapse");

console.log("cssAnimation.fadeSlideUpDown hide");
},
},

// 淡入淡出+左右滑动效果
fadeSlideLeftRight:
{
// 初始化
init: function($ele)
{
// 设置宽度
$ele.width($ele.width());

cssAnimation._init($ele, "fadeOut slideLeftRightCollapse");

console.log("cssAnimation.fadeSlideLeftRight init");
},

// 左右滑动显示
show: function($ele)
{
cssAnimation._show($ele, "fadeOut slideLeftRightCollapse");

console.log("cssAnimation.fadeSlideLeftRight show");
},

// 左右滑动隐藏
hide: function($ele)
{
cssAnimation._hide($ele, "fadeOut slideLeftRightCollapse");

console.log("cssAnimation.fadeSlideLeftRight hide");
},
},
};
/**************************** module 2: end ****************************/


/**************************** module 3: start ****************************/
let jsAnimation =
{
_init: function($ele, callback)
{
$ele.removeClass("transition");

init($ele, callback);
},

_show: function($ele, method)
{
show($ele, function()
{
$ele.stop()[method](function()
{
// 触发自定义shown事件,设置status状态
$ele.trigger("shown").data("status", "shown");
});
});
},

_hide: function($ele, method)
{
hide($ele, function()
{
$ele.stop()[method](function()
{
// 触发自定义hidden事件,设置status状态
$ele.trigger("hidden").data("status", "hidden");
});
});
},

_cusInit: function($ele, oProperty)
{
let styles = {};

for (let i in oProperty)
{
styles[i] = $ele.css(i);
}

// 保存元素的宽度信息
$ele.data("styles", styles);

jsAnimation._init($ele, function()
{
$ele.css(oProperty);
});
},

_cusShow: function($ele)
{
show($ele, function()
{
$ele.show();

$ele.stop().animate($ele.data("styles"), function()
{
// 动画结束后,触发shown事件,设置status状态
$ele.trigger("shown").data("status", "shown");
});
});
},

_cusHide: function($ele, oProperty)
{
hide($ele, function()
{
$ele.stop().animate(oProperty, function()
{
$ele.hide();

// 动画结束后,触发hidden事件,设置status状态
$ele.trigger("hidden").data("status", "hidden");
});
});
},

// 淡入淡出效果
fade:
{
// 初始化
init: function($ele)
{
jsAnimation._init($ele);

console.log("jsAnimation.fade init");
},

// 淡入
show: function($ele)
{
jsAnimation._show($ele, "fadeIn");

console.log("jsAnimation.fade show");
},

// 淡出
hide: function($ele)
{
jsAnimation._hide($ele, "fadeOut");

console.log("jsAnimation.fade hide");
},
},

// 上下滑动效果
slideUpDown:
{
// 初始化
init: function($ele)
{
jsAnimation._init($ele);

console.log("jsAnimation.slideUpDown init");
},

// 下滑显示
show: function($ele)
{
jsAnimation._show($ele, "slideDown");

console.log("jsAnimation.slideUpDown show");
},

// 上滑隐藏
hide: function($ele)
{
jsAnimation._hide($ele, "slideUp");

console.log("jsAnimation.slideUpDown hide");
},
},

// 左右滑动效果
slideLeftRight:
{
// 初始化
init: function($ele)
{
jsAnimation._cusInit($ele, {
"width": 0,
"padding-left": 0,
"padding-right": 0,
});

console.log("jsAnimation.slideLeftRight init");
},

// 显示
show: function($ele)
{
jsAnimation._cusShow($ele);

console.log("jsAnimation.slideLeftRight show");
},

// 隐藏
hide: function($ele)
{
jsAnimation._cusHide($ele, {
"width": 0,
"padding-left": 0,
"padding-right": 0,
});

console.log("jsAnimation.slideLeftRight hide");
},
},

// 淡入淡出+上下滑动
fadeSlideUpDown:
{
// 初始化
init: function($ele)
{
jsAnimation._cusInit($ele, {
"opacity": 0,
"height": 0,
"padding-top": 0,
"padding-bottom": 0,
});

console.log("jsAnimation.fadeSlideUpDown init");
},

// 显示
show: function($ele)
{
jsAnimation._cusShow($ele);

console.log("jsAnimation.fadeSlideUpDown show");
},

// 隐藏
hide: function($ele)
{
jsAnimation._cusHide($ele, {
"opacity": 0,
"height": 0,
"padding-top": 0,
"padding-bottom": 0,
});

console.log("jsAnimation.fadeSlideUpDown hide");
},
},

// 淡入淡出+左右滑动
fadeSlideLeftRight:
{
// 初始化
init: function($ele)
{
jsAnimation._cusInit($ele, {
"opacity": 0,
"width": 0,
"padding-left": 0,
"padding-right": 0,
});

console.log("jsAnimation.fadeSlideLeftRight init");
},

// 显示
show: function($ele)
{
jsAnimation._cusShow($ele);

console.log("jsAnimation.fadeSlideLeftRight show");
},

// 隐藏
hide: function($ele)
{
jsAnimation._cusHide($ele, {
"opacity": 0,
"width": 0,
"padding-left": 0,
"padding-right": 0,
});

console.log("jsAnimation.fadeSlideLeftRight hide");
},
},
};

/**************************** module 3: end ****************************/


/**************************** module 4: start ****************************/
function init($ele, hiddenCallback)
{
if ($ele.is(":hidden") || $ele.css("visibility") === "hidden")
{
$ele.data("status", "hidden");

typeof hiddenCallback === "function" ? hiddenCallback() : 1;
}
else
{
$ele.data("status", "shown");
}
}


function show($ele, callback)
{
// 若已显示,则返回
if ($ele.data("status") === "show" || $ele.data("status") === "shown")
{
return;
}

// 触发自定义的show事件,设置状态为show
$ele.trigger("show").data("status", "show");

callback();
}


function hide($ele, callback)
{
// 若已隐藏,则返回
if ($ele.data("status") === "hide" || $ele.data("status") === "hidden")
{
return;
}

// 触发自定义的hide事件,设置状态为hide
$ele.trigger("hide").data("status", "hide");

callback();
}

/**************************** module 4: end ****************************/


/**************************** module 5: start ****************************/
let defaults = {css: false, js: false, animation: "fade"};

function showHide($ele, options)
{
let mode = null;

// 使用CSS动画
if (options.css && MUTAO.isSupported)
{
mode = cssAnimation[options.animation] || cssAnimation[defaults.animation];
}
// 使用JS动画
else if (options.js)
{
mode = jsAnimation[options.animation] || jsAnimation[defaults.animation];
}
// 不使用动画
else
{
mode = silentAnimation;
}

mode.init($ele);

return {
show: $.proxy(mode.show, this, $ele),
hide: $.proxy(mode.hide, this, $ele),
};
}


$.fn.extend({
showHide: function(args)
{
return this.each(function()
{
let $this = $(this),
mode = $this.data("showHide"),
options = $.extend({}, defaults, typeof args === "object" && args);


if (!mode)
{
$this.data("showHide", mode = showHide($this, options));
}


(typeof mode[args]) === "function" ? mode[args]() : 1;
});
},
});
/**************************** module 5: end ****************************/

})(jQuery);


slider-slide.js如下:

(function($)
{
"use strict";


/************************ part 1 common start ************************/
let _init = function($ele)
{
this.$ele = $ele;
this.onX = parseFloat(this.$ele.css("left"));
this.onY = parseFloat(this.$ele.css("top"));
};

let _to = function(x, y, callback)
{
x = typeof x === "number" ? x : this.onX;
y = typeof y === "number" ? y : this.onY;

if (this.onX === x && this.onY === y)
{
return;
}

// 运动之前触发move事件
this.$ele.trigger("move", [this.$ele]);

typeof callback === "function" ? callback() : 1;

this.onX = x;
this.onY = y;
};
/************************ part 1 common end ************************/


/************************ part 2 silentSlide start ************************/
// 静止运动(无动画)
let silentSlide = function($ele)
{
_init.call(this, $ele);
this.$ele.removeClass("transition");
};

silentSlide.prototype.to = function(x, y)
{
let self = this;

_to.call(this, x, y, function()
{
self.$ele.css({
"left": x,
"top": y,
});

// 运动之后
self.$ele.trigger("moved", [self.$ele]);
});
};

silentSlide.prototype.x = function(x)
{
this.to(x);
};

silentSlide.prototype.y = function(y)
{
this.to(null, y);
};
/************************ part 2 silentSlide end ************************/


/************************ part 3 cssSlide start ************************/
// CSS实现动画
let cssSlide = function($ele)
{
_init.call(this, $ele);

this.$ele.addClass("transition");

this.$ele.css({
"left": this.onX,
"top": this.onY,
});
};

cssSlide.prototype.to = function(x, y)
{
let self = this;

_to.call(this, x, y, function()
{
self.$ele.off(window.MUTAO.transitionend).one(window.MUTAO.transitionend, function()
{
self.$ele.trigger("moved", [self.$ele]);
});

self.$ele.css({
"left": x,
"top": y,
});
});
};

cssSlide.prototype.x = function(x)
{
this.to(x);
};

cssSlide.prototype.y = function(y)
{
this.to(null, y);
};
/************************ part 3 cssSlide end ************************/


/************************ part 4 jsSlide start ************************/
// JS实现动画
let jsSlide = function($ele)
{
_init.call(this, $ele);

this.$ele.removeClass("transition");
};

jsSlide.prototype.to = function(x, y)
{
let self = this;

_to.call(this, x, y, function()
{
self.$ele.stop().animate({
"left": x,
"top": y,
}, function()
{
self.$ele.trigger("moved", [self.$ele]);
});
});
};

jsSlide.prototype.x = function(x)
{
this.to(x);
};

jsSlide.prototype.y = function(y)
{
this.to(null, y);

};
/************************ part 4 jsSlide end ************************/


/************************ part 5 move start ************************/
const DEFAULTS = {
css: false,
js: false,
};

let move = function($ele, options)
{
let mode = null;

// 使用CSS动画
if (options.css && window.MUTAO.isSupported)
{
mode = new cssSlide($ele);
}
// 使用JS动画
else if (options.js)
{
mode = new jsSlide($ele);
}
// 不使用动画
else
{
mode = new silentSlide($ele);
}

return {
to: $.proxy(mode.to, mode),
x: $.proxy(mode.x, mode),
y: $.proxy(mode.y, mode),
};
};

$.fn.move = function(option, x, y)
{
return this.each(function()
{
let $this = $(this),
mode = $this.data("move"),
args = $.extend({}, DEFAULTS,
typeof option === "object" && option);

!mode ? $this.data("move", mode = move($this, args)) : 1;

typeof mode[option] === "function" ? mode[option](x, y) : 1;
});
};
/************************ part 5 move end ************************/

})(jQuery);


slider-slide-new.js如下:

(function($)
{
    "use strict";


    function Slider($ele, options)
    {
        this.$ele = $ele;
        this.options = options;

        // 获取图片div
        this.$items = this.$ele.find(".slider__container__item");

        // 获取图片数量
        this.ITEM_NUM = this.$items.length;

        // 获取索引点
        this.$dots = this.$ele.find(".slider__index__dot");

        // 获取上一张、下一张按钮
        this.$btns = this.$ele.find(".ui-slider__btn");

        // 获取当前索引值
        this.onIdx = this.options.iniIdx;

        // 初始化
        this._init();
    }


    // 默认参数
    Slider.DEFAULTS = {
        css: false,
        js: false,
        animation: "fade", // "fade"为淡入淡出,"slide"为平移
        iniIdx: 0, // 初始显示的图片
        interval: 0, // 自动轮播的间隔时间(单位:毫秒。0表示不开启自动轮播)
        loop: false,
    };


    // 初始化函数
    Slider.prototype._init = function()
    {
        let self = this;

        // 显示当前索引点
        this.$dots.removeClass("slider__index__dot-on");
        this.$dots.eq(this.onIdx).addClass("slider__index__dot-on");

        // 选择切换方式(平移切换)
        if (this.options.animation === "slide")
        {
            this.$ele.addClass("slider-slide");

            this.setIdx = this._slide;

            this.$container = this.$ele.find(".slider__container");

            this.itemWidth = this.$items.eq(0).width();

            this.$container.css("left", -1 * this.onIdx * this.itemWidth);

            // move方法初始化
            this.$container.move(this.options);

            // 首尾图片无缝切换
            if (this.options.loop)
            {
                // 复制第一张图片到最后
                this.$container.append(this.$items.first().clone());

                this.transitionClass = this.$container.hasClass("transition") ? "transition" : "";

                ++this.ITEM_NUM;
            }
        }
        // 选择切换方式(淡入淡出切换)
        else
        {
            this.$ele.addClass("slider-fade");

            this.$items.eq(this.onIdx).show();

            // 发送消息
            this.$items.on("show shown hide hidden", function(e)
            {
                self.$ele.trigger("slider-" + e.type, [self.$items.index(this), this]);
            });

            // ShowHide方法初始化
            this.$items.showHide(this.options);

            this.setIdx = this._fade;
        }

        this.$ele.
            hover(function()
            {
                // 鼠标移入,按钮显示
                self.$btns.show();
            }, function()
            {
                // 鼠标移出,按钮隐藏
                self.$btns.hide();
            }).
            on("click", ".ui-slider__btn.left", function()
            {
                // 上一张按钮
                self.setIdx((self.onIdx - 1) % self.ITEM_NUM, 1);
            }).
            on("click", ".ui-slider__btn.right", function()
            {
                // 下一张按钮
                self.setIdx((self.onIdx + 1) % self.ITEM_NUM, -1);

                console.log(self.onIdx);
            }).
            on("click", ".slider__index__dot", function()
            {
                // 点击索引点,切换图片
                self.setIdx(self.$dots.index(this));

                console.log(self.onIdx);
            });

        // 开启自动轮播
        if (this.options.interval && !isNaN(this.options.interval))
        {
            this.$ele.hover($.proxy(this.endAutoplay, this), $.proxy(this.startAutoplay, this));
            this.startAutoplay();
        }
    }


    Slider.prototype._getIndex = function(idx, maxNum)
    {
        maxNum = maxNum || this.ITEM_NUM;

        if (isNaN(idx))
        {
            return 0;
        }

        if (idx < 0)
        {
            return maxNum - 1;
        }

        if (idx > maxNum - 1)
        {
            return 0;
        }

        return idx;
    }

    // 更改当前索引点
    Slider.prototype._setIdxDot = function(idx)
    {
        this.$dots.removeClass("slider__index__dot-on");

        this.$dots.eq(idx).addClass("slider__index__dot-on");
    };


    // 淡入淡出切换
    Slider.prototype._fade = function(newIdx)
    {
        if (this.onIdx === newIdx)
        {
            return;
        }

        // 旧图片隐藏
        this.$items.eq(this.onIdx).showHide("hide");

        // 新图片显示
        this.$items.eq(newIdx).showHide("show");

        // 更改当前索引点
        this._setIdxDot(newIdx);

        // 更改当前索引值
        this.onIdx = newIdx;
    }


    // 平移切换
    Slider.prototype._slide = function(newIdx, direct)
    {
        if (this.onIdx === newIdx)
        {
            return;
        }

        let self = this;

        this.$container.move("x", -1 * newIdx * this.itemWidth);

        // 修改当前索引值
        this.onIdx = newIdx;

        if (this.options.loop && direct)
        {
            // 点击下一张按钮
            if (direct < 0)
            {
                if (newIdx === 0)
                {
                    this.$container.removeClass(this.transitionClass).css("left", 0);

                    this.onIdx = newIdx = 1;

                    setTimeout(function()
                    {
                        self.$container.addClass(self.transitionClass).move("x", -1 * newIdx * self.itemWidth);
                    });
                }
            }
            // 点击上一张按钮
            else
            {
                if (newIdx === this.ITEM_NUM - 1)
                {
                    this.$container.removeClass(this.transitionClass).css("left", -1 * newIdx * this.itemWidth);

                    this.onIdx = newIdx = this.ITEM_NUM - 2;

                    setTimeout(function()
                    {
                        self.$container.addClass(self.transitionClass).move("x", -1 * newIdx * self.itemWidth);
                    });
                }
            }

            newIdx = this._getIndex(newIdx, this.ITEM_NUM - 1);
        }

        // 修改当前索引点
        this._setIdxDot(newIdx);
    }


    // 开始自动轮播
    Slider.prototype.startAutoplay = function()
    {
        let self = this;

        self.intervalID = setInterval(function()
        {
            self.setIdx((self.onIdx + 1) % self.ITEM_NUM);
        }, this.options.interval);
    }


    // 结束自动轮播
    Slider.prototype.endAutoplay = function()
    {
        clearInterval(this.intervalID);
    }


    // 在jQuery上自定义函数slider
    $.fn.slider = function(option)
    {
        return this.each(function()
        {
            let $this = $(this),
                funSlider = $this.data("slider"),
                args = $.extend(
                    {}, Slider.DEFAULTS, $this.data(),
                    typeof option === "object" && option);

            !funSlider ? $this.data("slider", funSlider = new Slider($this, args)) : 1;

            typeof funSlider[option] === "function" ? funSlider[option]() : 1;
        });
    };

})(jQuery);



写回答

1回答

好帮手慕久久

2020-11-25

同学你好,点击上一张图片时,(self.onIdx - 1) % self.ITEM_NUM的值是-1,即实际执行的是self.setIdx(-1, 1),由于-1这个索引没有对应的图片,所以切换不正常:
http://img.mukewang.com/climg/5fbdc58409f5523006480126.jpg

http://img.mukewang.com/climg/5fbdc58c091e38c205170155.jpg

需要校验一下索引是否是合理的,如下:

http://img.mukewang.com/climg/5fbdc5c1097bb8cc07520395.jpg

调整后,点击上一张按钮就可以无缝切换了。

祝学习愉快!

0

0 学习 · 14456 问题

查看课程