js 特效js库 妙味,轮播

功能介绍

    // 这段代码是在2016年6月5日创建的, 博主个人在项目里使用的特效库
/* 获取指定class的元素集合
 * 用法示例:var cda = getClass(document, 'da')[0];
 *
 * @param {Object} oParent - 父元素对象,从该元素内查找指定class的子元素
 * @param {string} className - 要查找的class名称
 * @returns {Array} - 返回符合条件的子元素集合
 */
function getClass(oParent, className) {
    var eLement = oParent.getElementsByTagName('*');
    var i = 0;
    var attr = [];
    for (i = 0; i < eLement.length; i++) {
        if (eLement[i].className == className) {
            attr.push(eLement[i]);
        }
    }
    return attr;
}

/* 设置元素的样式属性
 * 用法示例:setStyle(da, { backgroundColor: 'green', height: '200px' });
 *
 * @param {Object} obj - 要设置样式的元素对象
 * @param {Object} json - 包含样式属性和值的对象
 */
function setStyle(obj, json) {
    var attr = '';
    for (attr in json) {
        obj.style[attr] = json[attr];
    }
}

/* 添加指定class到元素
 * 用法示例:addClass(oLi[i], 'red');
 *
 * @param {Object} obj - 要添加class的元素对象
 * @param {string} className - 要添加的class名称
 */
function addClass(obj, className) {
    if (obj.className == '') {
        obj.className = className;
    } else {
        var arrClassName = obj.className.split(' ');
        if (arrIndexOf(arrClassName, className) == -1) {
            obj.className += ' ' + className;
        }
    }

    /* 在数组中查找指定值的索引位置
 *
 * @param {Array} arr - 要查找的数组
 * @param {any} v - 要查找的值
 * @returns {number} - 返回值在数组中的索引位置,如果未找到返回-1
 */


    function arrIndexOf(arr, v) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] == v) {
                return i;
            }
        }
        return -1;
    }
}

/* 删除指定class
 * 用法示例:removeClass(oW, "pageShow");
 *
 * @param {Object} obj - 要删除class的元素对象
 * @param {string} sClass - 要删除的class名称
 */
function removeClass(obj, sClass) {
    var aClass = obj.className.split(' ');
    if (!obj.className) return;
    for (var i = 0; i < aClass.length; i++) {
        if (aClass[i] === sClass) {
            aClass.splice(i, 1);
            obj.className = aClass.join(' ');
            break;
        }
    }
}

/* 获取元素样式属性,兼容IE
 * 用法示例:var styleValue = getStyle(obj, 'width');
 *
 * @param {Object} obj - 要获取样式属性的元素对象
 * @param {string} attr - 要获取的样式属性名称
 * @returns {string} - 返回样式属性值
 */
function getStyle(obj, attr) {
    if (obj.currentStyle) {
        return obj.currentStyle[attr];
    } else {
        return getComputedStyle(obj, 33)[attr];
    }
}

/* 缓冲运动效果
 * 用法示例:startMove(obj, { width: 200, opacity: 0.5 }, function() { // 动画结束后执行的回调 });
 *
 * @param {Object} obj - 要运动的元素对象
 * @param {Object} json - 包含要运动的属性和目标值的对象
 * @param {function} endFn - 动画结束后执行的回调函数
 */
function startMove(obj, json, endFn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        var bBtn = true; // 用于标记是否所有属性都到达目标值

        // 遍历 json 对象中的属性和目标值
        for (var attr in json) {
            var iCur = 0; // 当前属性值

            // 获取当前属性值,考虑 opacity 属性需要放大100倍
            if (attr == 'opacity') {
                if (Math.round(parseFloat(getStyle(obj, attr)) * 100) == 0) {
                    iCur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
                } else {
                    iCur = Math.round(parseFloat(getStyle(obj, attr)) * 100) || 100;
                }
            } else {
                iCur = parseInt(getStyle(obj, attr)) || 0;
            }

            // 计算速度
            var iSpeed = (json[attr] - iCur) / 8;
            iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);

            // 如果当前属性值不等于目标值,将 bBtn 设置为 false
            if (iCur != json[attr]) {
                bBtn = false;
            }

            // 根据属性类型设置属性值
            if (attr == 'opacity') {
                obj.style.filter = 'alpha(opacity=' + (iCur + iSpeed) + ')';
                obj.style.opacity = (iCur + iSpeed) / 100;
            } else {
                obj.style[attr] = iCur + iSpeed + 'px';
            }
        }

        // 如果所有属性都到达目标值,清除定时器并执行回调函数
        if (bBtn) {
            clearInterval(obj.timer);
            if (endFn) {
                endFn.call(obj);
            }
        }
    }, 30);
}

/* 时间版运动效果
 * 用法示例:timeMove(obj, { width: 200, opacity: 0.5 }, 1000, 'easeOut', function() { // 动画结束后执行的回调 });
 *
 * @param {Object} obj - 要运动的元素对象
 * @param {Object} json - 包含要运动的属性和目标值的对象
 * @param {number} time - 运动的总时间(毫秒)
 * @param {string} fx - 运动的缓冲函数名称(可选,默认为 'linear')
 * @param {function} fn - 动画结束后执行的回调函数(可选)
 */
function timeMove(obj, json, time, fx, fn) {
    // 设置默认值
    if (typeof time == 'undefined') {
        time = 400;
        fx = 'linear';
    }
    if (typeof time == 'string') {
        if (typeof fx == 'function') {
            fn = fx;
        }
        fx = time;
        time = 400;
    } else if (typeof time == 'function') {
        fn = time;
        time = 400;
        fx = 'linear';
    } else if (typeof time == 'number') {
        if (typeof fx == 'function') {
            fn = fx;
            fx = 'linear';
        } else if (typeof fx == 'undefined') {
            fx = 'linear';
        }
    }

    // 获取元素当前属性值
    var iCur = {};
    for (var attr in json) {
        iCur[attr] = 0;
        if (attr == 'opacity') {
            iCur[attr] = Math.round(getStyle(obj, attr) * 100);
        } else {
            iCur[attr] = parseInt(getStyle(obj, attr));
        }
    }

    // 记录运动开始的时间
    var timeStart = now();

    // 清除之前的定时器
    clearInterval(obj.tMtim);

    // 开始运动
    obj.tMtim = setInterval(function () {
        var timeNow = now();
        var t = time - Math.max(0, timeStart - timeNow + time); // 0到指定时间

        // 遍历属性,计算新的属性值
        for (var attr in json) {
            var value = Tween[fx](t, iCur[attr], json[attr] - iCur[attr], time);
            if (attr == 'opacity') {
                obj.style.opacity = value / 100;
                obj.style.filter = 'alpha(opacity=' + value + ')';
            } else {
                obj.style[attr] = value + 'px';
            }
        }

        // 动画结束,清除定时器并执行回调函数
        if (t == time) {
            clearInterval(obj.tMtim);
            if (fn) {
                fn.call(obj);
            }
        }
    }, 13);

    // 获取当前时间
    function now() {
        return (new Date()).getTime();
    }
}
var Tween = {
    linear: function (t, b, c, d){  //匀速
        return c*t/d + b;
    },
    easeIn: function(t, b, c, d){  //加速曲线
        return c*(t/=d)*t + b;
    },
    easeOut: function(t, b, c, d){  //减速曲线
        return -c *(t/=d)*(t-2) + b;
    },
    easeBoth: function(t, b, c, d){  //加速减速曲线
        if ((t/=d/2) < 1) {
            return c/2*t*t + b;
        }
        return -c/2 * ((--t)*(t-2) - 1) + b;
    },
    easeInStrong: function(t, b, c, d){  //加加速曲线
        return c*(t/=d)*t*t*t + b;
    },
    easeOutStrong: function(t, b, c, d){  //减减速曲线
        return -c * ((t=t/d-1)*t*t*t - 1) + b;
    },
    easeBothStrong: function(t, b, c, d){  //加加速减减速曲线
        if ((t/=d/2) < 1) {
            return c/2*t*t*t*t + b;
        }
        return -c/2 * ((t-=2)*t*t*t - 2) + b;
    },
    elasticIn: function(t, b, c, d, a, p){  //正弦衰减曲线(弹动渐入)
        if (t === 0) {
            return b;
        }
        if ( (t /= d) == 1 ) {
            return b+c;
        }
        if (!p) {
            p=d*0.3;
        }
        if (!a || a < Math.abs(c)) {
            a = c;
            var s = p/4;
        } else {
            var s = p/(2*Math.PI) * Math.asin (c/a);
        }
        return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
    },
    elasticOut: function(t, b, c, d, a, p){    //正弦增强曲线(弹动渐出)
        if (t === 0) {
            return b;
        }
        if ( (t /= d) == 1 ) {
            return b+c;
        }
        if (!p) {
            p=d*0.3;
        }
        if (!a || a < Math.abs(c)) {
            a = c;
            var s = p / 4;
        } else {
            var s = p/(2*Math.PI) * Math.asin (c/a);
        }
        return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
    },
    elasticBoth: function(t, b, c, d, a, p){
        if (t === 0) {
            return b;
        }
        if ( (t /= d/2) == 2 ) {
            return b+c;
        }
        if (!p) {            p = d*(
            0.3*1.5);
        }
        if ( !a || a < Math.abs(c) ) {            a = c
        ;
            var s = p/4;
        }
        else {
            var s = p/(2*Math.PI) * Math.asin (c/a);
        }
        if (t < 1) {
            return - 0.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
        }
        return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
    },
    backIn: function(t, b, c, d, s){     //回退加速(回退渐入)
        if (typeof s == 'undefined') {            s =
            1.70158;
        }
        return c*(t/=d)*t*((s+1)*t - s) + b;
    },
    backOut: function(t, b, c, d, s){
        if (typeof s == 'undefined') {            s =
            3.70158;  //回缩的距离
        }
        return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
    },
    backBoth: function(t, b, c, d, s){
        if (typeof s == 'undefined') {            s =
            1.70158;
        }
        if ((t /= d/2 ) < 1) {
            return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
        }
        return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
    },
    bounceIn: function(t, b, c, d){    //弹球减振(弹球渐出)
        return c - Tween['bounceOut'](d-t, 0, c, d) + b;
    },
    bounceOut: function(t, b, c, d){
        if ((t/=d) < (1/2.75)) {
            return c*(7.5625*t*t) + b;
        } else if (t < (2/2.75)) {
            return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
        } else if (t < (2.5/2.75)) {
            return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
        }
        return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
    },
    bounceBoth: function(t, b, c, d){
        if (t < d/2) {
            return Tween['bounceIn'](t*2, 0, c, d) * 0.5 + b;
        }
        return Tween['bounceOut'](t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
    }}

/* 选项卡组件
 * 用法示例:var tab = new Tab('ul_li', 'ol_li');  // 创建选项卡实例
 * tab.fo('onmouseover'); // 设置切换方式为鼠标悬停
 * tab.autoplay('onmouseover', 2500); // 启用自动播放,切换方式为鼠标悬停,切换间隔为 2500 毫秒
 *
 * @param {string} uli - 选项卡标题的类名
 * @param {string} oli - 选项卡内容的类名
 */
function Tab(uli, oli) {
    this.ulLi = getClass(document, uli); // 选项卡标题元素数组
    this.olLi = getClass(document, oli); // 选项卡内容元素数组
    this.num = 0; // 当前选项卡索引
    this.timer = null; // 自动播放定时器
    this.olLi[0].style.display = 'block'; // 初始化显示第一个选项卡内容
    addClass(this.ulLi[0], 'active'); // 初始化给第一个选项卡标题添加 'active' 类
}

/* 设置选项卡切换方式
 *
 * @param {string} event - 切换方式,可以是 'onclick' 或 'onmouseover'
 */
Tab.prototype.fo = function (event) {
    var This = this;
    for (var i = 0; i < this.ulLi.length; i++) {
        this.ulLi[i].index = i;
        if (event) { // 如果传参了切换方式
            if (event == 'onclick') {
                this.ulLi[i].onclick = function () {
                    This.clik(this);
                }
            }
            if (event == 'onmouseover') {
                this.ulLi[i].onmouseover = function () {
                    This.clik(this);
                }
            }
        } else { // 如果没有传参,默认为 'onclick'
            this.ulLi[i].onclick = function () {
                This.clik(this);
            }
        }
    }
}

/* 执行选项卡切换
 *
 * @param {HTMLElement} obj - 触发切换的元素对象
 */
Tab.prototype.clik = function (obj) {
    for (var j = 0; j < this.ulLi.length; j++) {
        removeClass(this.ulLi[j], 'active'); // 移除所有选项卡标题的 'active' 类
        this.olLi[j].style.display = 'none'; // 隐藏所有选项卡内容
    }
    addClass(obj, 'active'); // 给当前选项卡标题添加 'active' 类
    this.olLi[obj.index].style.display = 'block'; // 显示当前选项卡内容
}

/* 启用自动播放
 *
 * @param {string} event - 切换方式,可以是 'onclick' 或 'onmouseover'
 * @param {number} time - 自动切换的间隔时间(毫秒)
 */
Tab.prototype.autoplay = function (event, time) {
    time ? time : time = 2000; // 如果未传入时间参数,默认为 2000 毫秒
    var This = this;
    clearInterval(This.timer); // 清除之前的自动播放定时器
    This.timer = setInterval(function () {
        This.num == This.ulLi.length - 1 ? This.num = 0 : This.num++; // 切换到下一个选项卡
        for (var i = 0; i < This.ulLi.length; i++) {
            This.ulLi[i].index = i;
            if (event) { // 如果传参了切换方式
                if (event == 'onclick') {
                    This.ulLi[i].onclick = function () {
                        This.num = this.index; // 点击切换时更新当前索引
                        xs(); // 执行切换
                        This.autoplay('onclick', time); // 继续自动播放
                    }
                } else if (event == 'onmouseover') {
                    This.ulLi[i].onmouseover = function () {
                        This.num = this.index; // 鼠标悬停切换时更新当前索引
                        xs(); // 执行切换
                        This.autoplay('onmouseover', time); // 继续自动播放
                    }
                }
            } else { // 如果没有传参,默认为 'onclick'
                This.ulLi[i].onclick = function () {
                    This.num = this.index; // 点击切换时更新当前索引
                    xs(); // 执行切换
                    This.autoplay(); // 继续自动播放
                }
            }
        }
        xs(); // 执行切换
        function xs() {
            for (var j = 0; j < This.ulLi.length; j++) {
                removeClass(This.ulLi[j], 'active'); // 移除所有选项卡标题的 'active' 类
                This.olLi[j].style.display = 'none'; // 隐藏所有选项卡内容
            }
            addClass(This.ulLi[This.num], 'active'); // 给当前选项卡标题添加 'active' 类
            This.olLi[This.num].style.display = 'block'; // 显示当前选项卡内容
        }
    }, time);
};


/* 拖拽组件
 * 用法示例:var drag = new Drag(); drag.init({ name: 'div1', toDown: function() {...}, toUp: function() {...} });
 * 传入参数对象 opts 包括 div 元素的 id(name),鼠标按下时的回调函数 toDown,鼠标抬起时的回调函数 toUp
 *
 * @constructor
 */
function Drag() {
    this.div = null; // 拖拽的元素
    this.disX = 0; // 鼠标按下时的 X 坐标偏移
    this.disY = 0; // 鼠标按下时的 Y 坐标偏移
    this.settings = { // 默认参数值为空
        toDown: function () {},
        toUp: function () {}
    };
}

/* 初始化拖拽功能
 *
 * @param {object} opts - 参数对象,包括 id(name)、toDown 和 toUp 回调函数
 */
Drag.prototype.init = function (opts) {
    this.div = getClass(document, opts.name)[0]; // 获取拖拽的元素
    for (var i in opts) {
        this.settings[i] = opts[i]; // 将传入的参数赋值给设置
    }
    var This = this;
    this.div.onmousedown = function (ev) {
        var ev = ev || window.event;
        This.down(ev);
        This.settings.toDown(); // 执行鼠标按下时的回调函数
        return false; // 阻止默认拖拽行为
    }
};

/* 鼠标按下事件处理函数
 *
 * @param {object} ev - 鼠标事件对象
 */
Drag.prototype.down = function (ev) {
    var This = this;
    this.disX = ev.clientX - this.div.offsetLeft; // 获取鼠标按下时的 X 坐标偏移
    this.disY = ev.clientY - this.div.offsetTop; // 获取鼠标按下时的 Y 坐标偏移
    document.onmousemove = function (ev) {
        var ev = ev || window.event;
        This.move(ev);
    };
    document.onmouseup = function () {
        This.up();
        This.settings.toUp(); // 执行鼠标抬起时的回调函数
    };
};

/* 鼠标移动事件处理函数
 *
 * @param {object} ev - 鼠标事件对象
 */
Drag.prototype.move = function (ev) {
    this.div.style.left = ev.clientX - this.disX + 'px'; // 设置元素的左偏移
    this.div.style.top = ev.clientY - this.disY + 'px'; // 设置元素的上偏移
};

/* 鼠标抬起事件处理函数 */
Drag.prototype.up = function () {
    document.onmousemove = null; // 清除鼠标移动事件
    document.onmouseup = null; // 清除鼠标抬起事件
};


/* 倒计时组件
 * 用法示例:var countdown = new Djs(); countdown.init('div');
 * 参数 obj 为包含倒计时日期的元素的 id
 *
 * @constructor
 */
function Djs() {}

/* 初始化倒计时功能
 *
 * @param {string} obj - 倒计时日期元素的 id
 */
Djs.prototype.init = function (obj) {
    var This = this;
    this.ob = getClass(document, obj)[0]; // 获取倒计时日期元素
    clearInterval(this.timer); // 清除之前的计时器
    this.timer = setInterval(function () {
        var szsj = new Date(This.ob.attributes['date'].nodeValue.replace(/-/g, '/')).getTime(); // 获取目标日期时间戳
        var xzsj = new Date();
        var t = szsj - xzsj;
        var day = 0,
            hour = 0,
            min = 0,
            s = 0;
        if (t >= 0) {
            day = Math.floor(t / 1000 / 60 / 60 / 24);
            hour = Math.floor(t / 1000 / 60 / 60 % 24);
            min = Math.floor(t / 1000 / 60 % 60);
            s = Math.floor(t / 1000 % 60);
        } else {
            This.ob.parentNode.parentNode.parentNode.parentNode.removeChild(This.ob.parentNode.parentNode.parentNode); // 倒计时结束后移除元素
            clearInterval(obj.timer); // 清除计时器
        }
        This.ob.innerHTML =
            '剩余时间:<b>' + day + '</b>天<b>' + hour + '</b>时<b>' + min + '</b>分<b>' + s + '</b>秒';
    }, 1000);
};

/**
 * 滚动固定顶部导航
 * 用法示例:
 * var sdc = new Gdnav();
 * sdc.init('div'); // 传入要固定的导航栏的标签名或类名
 */
function Gdnav() {}
// 初始化方法,用于设置滚动固定顶部导航效果
Gdnav.prototype.init = function (obj) {
    // 获取要固定的导航栏元素
    this.oNav = getClass(document, obj)[0];
    var This = this;
    var offsetTop = This.oNav.offsetTop;

    // 监听页面滚动事件
    window.onscroll = function () {
        var scroll = document.documentElement.scrollTop || document.body.scrollTop;

        // 当滚动位置超过导航栏的原始位置时,将导航栏固定在页面顶部
        if (scroll > offsetTop) {
            This.oNav.style.position = 'fixed';
            This.oNav.style.zIndex = 1000;
            This.oNav.style.top = '0';
            This.oNav.style.left = '0';
        } else {
            This.oNav.style.position = 'static';
        }
    };
};

/* 无缝滚动初始化函数
 * 用法示例:
 * var move = new Wfgd();
 * move.init('ul', -2);
 *
 * @constructor
 */
function Wfgd() {
    this.timer = null;
}

// 初始化无缝滚动
// 参数 ul:包含滚动内容的 ul 元素的选择器或标签名
// 参数 ispeed:滚动速度,正数向左滚动,负数向右滚动
Wfgd.prototype.init = function (ul, ispeed) {
    // 获取滚动内容的 ul 元素
    this.ul = getClass(document, ul)[0];
    // 设置滚动速度
    this.ispeed = ispeed;
    // 将滚动内容复制一份并追加到原内容后,实现无缝滚动
    this.ul.innerHTML += this.ul.innerHTML;
    // 获取第一个子元素和子元素个数
    this.uChildF = this.ul.children[0];
    this.uLength = this.ul.children.length;
    this.uMar = null;
    this.iSpeed = 1;
    // 计算所有子元素的marginLeft之和,用于设置ul的宽度
    for (var i = 0; i < this.uLength; i++) {
        this.uMar += parseInt(getStyle(this.ul.children[i], 'marginLeft'));
    }
    this.ul.style.width = this.uLength * this.uChildF.offsetWidth + this.uMar + 'px';
    this.time(ispeed); // 启动滚动
    this.over(ispeed); // 鼠标悬停停止滚动
};

// 启动定时器实现滚动
Wfgd.prototype.time = function () {
    var This = this;
    this.timer = setInterval(function () {
        WfgdFn(This, This.ispeed);
    }, 30);
};

// 鼠标悬停停止滚动
Wfgd.prototype.over = function () {
    var This = this;
    this.ul.onmouseover = function () {
        clearInterval(This.timer);
    };
    this.ul.onmouseout = function () {
        This.timer = setInterval(function () {
            WfgdFn(This, This.ispeed);
        }, 30);
    };
};

// 滚动函数
function WfgdFn(This) {
    if (This.ul.offsetLeft < -This.ul.offsetWidth / 2) {
        This.ul.style.left = 0;
    } else if (This.ul.offsetLeft > 0) {
        This.ul.style.left = -This.ul.offsetWidth / 2 + 'px';
    }
    This.ul.style.left = This.ul.offsetLeft + This.ispeed + 'px';
}

/* 无缝滚动结束 */

/* PC轮播初始化函数
 *
 * @constructor
 */
function Pclb() {
    this.settings = {};
}

/* 初始化PC轮播
 *
 * @param {Object} opts - 包含各种配置的对象
 * @param {number} number - 轮播间隔时间
 * @param {string} fx - 轮播特效,可选,默认为'linear'
 * @param {function} fn - 回调函数,可选
 */
// 用法示例
// var move = new Pclb();
// move.init({
//     warp: 'warp', // 轮播容器的类名
//     box: 'box', // 轮播框的类名
//     ul: 'ul', // 轮播项的类名
//     prev: 'prev', // 上一张按钮的类名
//     next: 'next', // 下一张按钮的类名
//     foucs: 'defo' // 焦点按钮容器的类名
// }, 2000, fx, fn); // 设置轮播间隔时间、特效、回调函数等参数

Pclb.prototype.init = function (opts, number, fx, fn) {
    var This = this;

    // 复制配置对象中的参数到实例对象
    for (var i in opts) {
        this.settings[i] = opts[i];
    }

    // 获取各个轮播相关的 DOM 元素
    this.warp = getClass(document, opts.warp)[0];
    this.box = getClass(document, opts.box)[0];
    this.ul = getClass(document, opts.ul)[0];
    this.prev = getClass(document, opts.prev)[0];
    this.next = getClass(document, opts.next)[0];
    this.foucs = getClass(document, opts.foucs)[0];

    // 初始化一些轮播所需的变量和配置
    this.num = 0;
    this.num2 = 0;
    this.timer = 0;
    this.number = number;
    this.fx = fx || 'linear'; // 默认为'linear'特效
    this.fn = fn;
    this.kg = true;
    this.liFirst = this.ul.children[0];
    this.liFirstW = this.liFirst.offsetWidth;
    this.ul.appendChild(this.liFirst.cloneNode(true));
    this.liLeng = this.ul.children.length;
    this.ul.style.width = this.liFirstW * this.ul.children.length + 'px';
    this.warp.style.position = 'relative';
    this.box.style.width = this.liFirst.offsetWidth + 'px';
    this.box.style.margin = '0 auto';
    this.box.style.overflow = 'hidden';

    // 如果存在上一张按钮,则设置其样式
    if (this.prev) {
        this.prev.style.position = 'absolute';
        this.prev.style.zIndex = '10';
        this.next.style.position = 'absolute';
        this.next.style.zIndex = '10';
    }

    // 如果存在焦点按钮,则设置其样式
    if (this.foucs) {
        this.foucs.style.position = 'absolute';
        this.foucs.style.zIndex = '10';
        this.foucs.style.width = '100%';
        this.foucs.style.textAlign = 'center';

        // 为每个轮播项生成一个焦点按钮
        for (var i = 0; i < this.liLeng - 1; i++) {
            this.foucs.innerHTML += "<span class='lbFoucs' style='display:inline-block;'></span>";
        }

        // 设置焦点按钮的样式和点击事件处理程序
        this.foucsChild = this.foucs.children;
        for (var i = 0; i < this.liLeng - 1; i++) {
            this.foucsChild[i].style.cursor = 'pointer';
        }
        addClass(this.foucsChild[0], 'active');
        for (var i = 0; i < this.liLeng - 1; i++) {
            this.foucsChild[i].index = i;
            this.foucsChild[i].onclick = function () {
                for (var j = 0; j < This.liLeng - 1; j++) {
                    removeClass(This.foucsChild[j], 'active');
                }
                addClass(This.foucsChild[this.index], 'active');
                This.num = this.index;
                This.num2 = This.num;
                This.lb();
            };
        }
    }

    // 添加鼠标悬停和移出事件处理程序
    this.hover();

    // 启动轮播定时器
    This.timer = setInterval(function () {
        This.you();
        This.lb();
    }, This.number);

    // 如果存在上一张和下一张按钮,则添加点击事件处理程序
    if (this.prev) {
        this.pre();
        this.nex();
    }
};

/* 鼠标悬停停止轮播 */
Pclb.prototype.hover = function () {
    var This = this;
    this.warp.onmouseover = function () {
        clearInterval(This.timer);
    };
    this.warp.onmouseout = function () {
        This.timer = setInterval(function () {
            This.you();
            This.lb();
        }, This.number);
    };
};

/* 点击上一张按钮 */
Pclb.prototype.pre = function () {
    var This = this;
    this.prev.onclick = function () {
        This.num--;
        This.num2--;
        if (This.num < 0) {
            This.num = This.liLeng - 2;
            This.ul.style.marginLeft = -This.liFirstW * (This.liLeng - 1) + 'px';
        }
        if (This.num2 < 0) {
            This.num2 = This.liLeng - 2;
        } else if (This.num2 > This.liLeng - 2) {
            This.num2 = 0;
        }
        This.lb();
    };
};

/* 点击下一张按钮 */
Pclb.prototype.nex = function () {
    var This = this;
    this.next.onclick = function () {
        This.you();
        This.lb();
    };
};

/* 切换到下一张轮播项 */
Pclb.prototype.you = function () {
    var This = this;
    This.num++;
    This.num2++;
    if (This.num > This.liLeng - 1) {
        This.num = 1;
        This.ul.style.marginLeft = 0;
    }
    if (This.num2 > This.liLeng - 2) {
        This.num2 = 0;
    }
};

/* 切换轮播项 */
Pclb.prototype.lb = function () {
    var This = this;
    timeMove(This.ul, {
        marginLeft: -This.num * This.liFirstW
    }, This.fx, This.fn);
    if (This.foucs) {
        for (var i = 0; i < This.liLeng - 1; i++) {
            for (var j = 0; j < This.liLeng - 1; j++) {
                removeClass(This.foucsChild[j], 'active');
            }
            addClass(This.foucsChild[This.num2], 'active');
        }
    }
};


posted on 2021-10-26 22:51  完美前端  阅读(69)  评论(0)    收藏  举报

导航