一个简单的跑马灯效果

方文锋  2022-09-15 17:27:07  1433  首页学习JavaScript

由于公司的业务需求,需要一个跑马灯的效果,然后我就动手写了,可以上下左右滚动。代码如下:


<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>跑马灯插件示例</title>
    <script src='/static/js2019/jquery-3.3.1.min.js' type="text/javascript"></script>
    <style type="text/css">
        *{margin:0;padding:0;font-size:14px;line-height:1.4;text-decoration:none;list-style:none;box-sizing:border-box;}body{padding:5px 8px;}
        .f-title{padding:0 0 0 20px;margin:15px 0;font-size:25px;color:#009f95;border-left:solid #009f95 5px;}
        .f-box-01,.f-box-02{width:200px;height:300px;border:solid #d1d1d1 1px;overflow:hidden;}
        .f-box-02{height:30px;}
        .f-box-01 .f-box-parent{display:inline-block;position:relative;width:100%;}
        .f-box-01 .f-box-child p{padding:5px 0 5px 5px;}
        .f-box-02 .f-box-parent{display:inline-block;position:relative;width:calc(50px * 32);}
        .f-box-02 .f-box-child{float:left;}
        .f-box-02 .f-box-child p{display:inline-block;float:left;padding:0 5px;text-align:center;width:50px;line-height:30px;}
    </style>
</head>
<body>
<p class="f-title">向上滚动</p>
<div class="f-box-01">
    <div class="f-box-parent" id="Y_top">
        <div class="f-box-child">
            <p>01</p>
            <p>02</p>
            <p>03</p>
            <p>04</p>
            <p>05</p>
            <p>06</p>
            <p>07</p>
            <p>08</p>
            <p>09</p>
            <p>10</p>
            <p>11</p>
            <p>12</p>
            <p>13</p>
            <p>14</p>
            <p>15</p>
        </div>
    </div>
</div>
<p class="f-title">向下滚动</p>
<div class="f-box-01">
    <div class="f-box-parent" id="Y_bottom">
        <div class="f-box-child">
            <p>01</p>
            <p>02</p>
            <p>03</p>
            <p>04</p>
            <p>05</p>
            <p>06</p>
            <p>07</p>
            <p>08</p>
            <p>09</p>
            <p>10</p>
            <p>11</p>
            <p>12</p>
            <p>13</p>
            <p>14</p>
            <p>15</p>
        </div>
    </div>
</div>
<p class="f-title">向左滚动</p>
<div class="f-box-02">
    <div class="f-box-parent" id="X_left">
        <div class="f-box-child">
            <p>01</p>
            <p>02</p>
            <p>03</p>
            <p>04</p>
            <p>05</p>
            <p>06</p>
            <p>07</p>
            <p>08</p>
            <p>09</p>
            <p>10</p>
            <p>11</p>
            <p>12</p>
            <p>13</p>
            <p>14</p>
            <p>15</p>
        </div>
    </div>
</div>
<p class="f-title">向右滚动</p>
<div class="f-box-02">
    <div class="f-box-parent" id="X_right">
        <div class="f-box-child">
            <p>01</p>
            <p>02</p>
            <p>03</p>
            <p>04</p>
            <p>05</p>
            <p>06</p>
            <p>07</p>
            <p>08</p>
            <p>09</p>
            <p>10</p>
            <p>11</p>
            <p>12</p>
            <p>13</p>
            <p>14</p>
            <p>15</p>
        </div>
    </div>
</div>
<div style="height:50px;width:100%;"></div>
<!--js 引用部分 start-->
<script src='/static/js/app.min.js' type="text/javascript"></script>
<!--js 引用部分 end-->
<script type="text/javascript">
    /**
     * 判断是否是数组
     * @param argument
     * @param {number|boolean} opt 是否用严格模式
     * @return {*}
     */
    function is_array(argument, opt) {
        if (opt === 1 || opt === true) {
            return Object.prototype.toString.call(argument) === "[object Array]";
        }
        return argument && (typeof argument === "object") && ("length" in argument) && (typeof argument.length === "number");
    }

    /**
     * 判断是否是对象
     * @param argument
     * @return {*}
     */
    function is_object(argument) {
        if (argument && (typeof argument === "object") && ("length" in argument)) {
            return Object.prototype.toString.call(argument) === "[object Object]";
        }
        return argument && (typeof argument === "object") && !("length" in argument);
    }

    /**
     * 判断是否是函数
     * @param argument
     * @return {*|boolean}
     */
    function is_function(argument) {
        return typeof argument === "function";
    }

    /**
     * 判断是否是字符串
     * @param argument
     * @return {*|boolean}
     */
    function is_string(argument) {
        return typeof argument === "string";
    }

    /**
     * 判断是否是布尔值
     * @param argument
     * @return {boolean}
     */
    function is_boolean(argument) {
        return typeof argument === "boolean";
    }

    /**
     * 判断是否是数字
     * @param argument
     * @return {boolean}
     */
    function is_number(argument) {
        return typeof argument === "number";
    }

    /**
     * 判断是否是未定义
     * @param argument
     * @return {boolean}
     */
    function is_undefined(argument) {
        return typeof argument === "undefined";
    }

    /**
     * 判断是否是空值
     * @param argument
     * @return {boolean}
     */
    function is_null(argument) {
        return argument === null || argument === "";
    }

    /**
     * 是否存在[true存在,false不存在]
     * @param argument
     * @param {array} opt 这里面的值是代表“不存在”
     * @return {boolean}
     */
    function is_exist(argument, opt) {
        opt || (opt = ["", null, false, undefined]);
        for (var k in opt) {
            if (opt[k] === argument) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断是否是整数
     * @param vars
     * @return {boolean}
     */
    function is_int(vars) {
        return /^[-]{0,1}\d+$/i.test(vars + "");
    }

    /**
     * 判断是否是小数
     * @param vars
     * @return {boolean}
     */
    function is_float(vars) {
        return /^[-]{0,1}[0-9]+\.{0,1}[0-9]*$/i.test(vars + "")
    }

    /**
     * 是否是html标签元素
     * @param argument
     * @returns {boolean}
     */
    function is_element(argument) {
        var reg = /^(\[object HTML[A-Za-z]+Element\])$/i;
        return reg.test(Object.prototype.toString.call(argument));
    }

    /**
     * 搜索数组中是否存在指定的值
     * @param {string} needle
     * @param {array} haystack
     * @param {boolean} argStrict
     * @return {boolean}
     */
    function in_array(needle, haystack, argStrict) {
        var key = "", strict = !!argStrict;
        if (strict) {
            for (key in haystack) {
                if (haystack[key] === needle) {
                    return true
                }
            }
        } else {
            for (key in haystack) {
                if (haystack[key] == needle) {
                    return true
                }
            }
        }
        return false
    }

    //跑马灯
    function marquee() {
        for (var i = 0, len = arguments.length; i < len; i++) {
            if (typeof arguments[i] === "function") {
                arguments[i].call(this);
            }
        }
        this.initialized = function (parentE, childE, directionXY, TB_LR, step) {
            if (is_element(parentE) && is_element(childE)) {
                var cloneE = childE.cloneNode(true);
                parentE.appendChild(cloneE);
                if (directionXY.toLocaleLowerCase() === "x") {
                    if (in_array(TB_LR.toLocaleLowerCase(), ["r", "right"])) {
                        cloneE.style.position = "relative";
                        cloneE.style.left = -2 * childE.offsetWidth + "px";
                    }
                }
                if (directionXY.toLocaleLowerCase() === "y") {
                    if (in_array(TB_LR.toLocaleLowerCase(), ["b", "bottom"])) {
                        cloneE.style.position = "relative";
                        cloneE.style.top = -2 * childE.offsetHeight + "px";
                    }
                }
            }
            this.attr("parentE", parentE).attr("childE", childE).attr("directionXY", directionXY).attr("TB_LR", TB_LR).attr("step", step);
            return this;
        };

        /**
         * 获取单位前的数值
         * @param idd
         * @param t 频率
         * @return {*}
         */
        this.animate = function (idd, t) {
            self = this;
            idd = idd ? "setInterval_ID" + idd : "setInterval_ID";
            (t) || (t = 1000 / 60);
            var parentE = this.attr("parentE");
            var childE = this.attr("childE");
            var directionXY = this.attr("directionXY");
            var TB_LR = this.attr("TB_LR");
            var step = this.attr("step");
            clearInterval(this.attr(idd));
            if (directionXY.toLocaleLowerCase() === "x") {
                self[idd] = setInterval(function () {
                    self.directionX(parentE, childE, TB_LR, step);
                }, t);
            }
            if (directionXY.toLocaleLowerCase() === "y") {
                self[idd] = setInterval(function () {
                    self.directionY(parentE, childE, TB_LR, step);
                }, t);
            }
            return this;
        };
        /**
         * 暂停
         * @param {string} idd
         * @return {*}
         */
        this.pause = function (idd) {
            idd = idd ? "setInterval_ID" + idd : "setInterval_ID";
            clearInterval(this[idd]);
            return this;
        };
        /**
         * 继续
         * @param {string} idd
         * @param {number} t 频率
         * @return {*}
         */
        this.continue = function (idd, t) {
            this.animate(idd, t);
            return this;
        };
        this.animate_top = function (parentE, childE, step, t, idd) {
            this.initialized(parentE, childE, "Y", "top", step).animate(idd, t);
            return this;
        };
        this.animate_bottom = function (parentE, childE, step, t, idd) {
            this.initialized(parentE, childE, "Y", "bottom", step).animate(idd, t);
            return this;
        };
        this.animate_left = function (parentE, childE, step, t, idd) {
            this.initialized(parentE, childE, "X", "l", step).animate(idd, t);
            return this;
        };
        this.animate_right = function (parentE, childE, step, t, idd) {
            this.initialized(parentE, childE, "X", "r", step).animate(idd, t);
            return this;
        };
        //设置对象属性不可修改,不可删除,不可枚举
        var O = {writable: false, configurable: false, enumerable: false};
        attr_list = ["getNum", "directionY", "directionX", "attr"];
        for (i = 0, len = attr_list.length; i < len; i++) {
            Object.defineProperty(marquee.prototype, attr_list[i], O);
        }
    }

    /**
     * 获取单位前的数值
     * @param str
     * @param unit
     * @return {number}
     */
    marquee.prototype.getNum = function (str, unit) {
        unit || (unit = "px");
        var index = str.indexOf(unit);
        return index > -1 ? parseFloat(str.substr(0, index)) : 0;
    };
    /**
     * 纵向滚动
     * @param parentE
     * @param childE
     * @param {string} T_B 滚动方向
     * @param {string|number} step 步进
     */
    marquee.prototype.directionY = function (parentE, childE, T_B, step) {
        T_B || (T_B = "T");
        step || (step = 1);
        if (Math.abs(this.getNum(parentE.style.top)) >= childE.clientHeight) {
            parentE.style.top = "0px";
        } else {
            var top = parentE.style.top;
            if (in_array(T_B.toLocaleLowerCase(), ["t", "top"])) {
                //向上滚动
                parentE.style.top = this.getNum(top) - parseFloat(step) + "px";
            }
            if (in_array(T_B.toLocaleLowerCase(), ["b", "bottom"])) {
                //向下滚动
                parentE.style.top = this.getNum(top) + parseFloat(step) + "px";
            }
        }
    };
    /**
     * 横向滚动
     * @param parentE
     * @param childE
     * @param {string} L_R 滚动方向
     * @param {string|number} step 步进
     */
    marquee.prototype.directionX = function (parentE, childE, L_R, step) {
        L_R || (L_R = "L");
        step || (step = 1);
        if (Math.abs(this.getNum(parentE.style.left)) >= childE.clientWidth) {
            parentE.style.left = "0px";
        } else {
            var left = parentE.style.left;
            if (in_array(L_R.toLocaleLowerCase(), ["l", "left"])) {
                //向左滚动
                parentE.style.left = this.getNum(left) - parseFloat(step) + "px";
            }
            if (in_array(L_R.toLocaleLowerCase(), ["r", "right"])) {
                //向右滚动
                parentE.style.left = this.getNum(left) + parseFloat(step) + "px";
            }
        }
    };
    /**
     * 设置和获取属性
     * @param {string|number|object} name
     * @param {*} value
     * @return {*}
     */
    marquee.prototype.attr = function (name, value) {
        var i, attr;
        if (is_exist(name) && (is_string(name) || is_number(name)) && is_exist(value)) {
            if (!in_array(name, ["getNum", "directionY", "directionX", "attr"])) {
                this[name] = value;
            }
        } else if (is_exist(name) && is_object(name)) {
            for (attr in name) {
                this.attr(attr, name[attr]);
            }
        } else if (is_exist(name) && (is_string(name) || is_number(name)) && !is_exist(value)) {
            return this[name];
        }
        return this;
    };


    $(function () {
        var pE_top = $("#Y_top"), pE_bottom = $("#Y_bottom"), pE_left = $("#X_left"), pE_right = $("#X_right");
        var cE_top = $(".f-box-child", pE_top[0]), cE_bottom = $(".f-box-child", pE_bottom[0]), cE_left = $(".f-box-child", pE_left[0]), cE_right = $(".f-box-child", pE_right[0]);
        var mar_top = new marquee(), mar_bottom = new marquee(), mar_left = new marquee(), mar_right = new marquee();

        //向上滚动
        mar_top.animate_top(pE_top[0], cE_top[0], 1);
        pE_top.unbind("mouseover").on("mouseover",function (e) {
            mar_top.pause();
        });
        pE_top.unbind("mouseout").on("mouseout",function (e) {
            mar_top.continue();
        });
        //向下滚动
        mar_bottom.animate_bottom(pE_bottom[0], cE_bottom[0], 1);
        pE_bottom.unbind("mouseover").on("mouseover",function (e) {
            mar_bottom.pause();
        });
        pE_bottom.unbind("mouseout").on("mouseout",function (e) {
            mar_bottom.continue();
        });
        //向左滚动
        mar_left.animate_left(pE_left[0], cE_left[0], 1);
        pE_left.unbind("mouseover").on("mouseover",function (e) {
            mar_left.pause();
        });
        pE_left.unbind("mouseout").on("mouseout",function (e) {
            mar_left.continue();
        });
        //向右滚动
        mar_right.animate_right(pE_right[0], cE_right[0], 1);
        pE_right.unbind("mouseover").on("mouseover",function (e) {
            mar_right.pause();
        });
        pE_right.unbind("mouseout").on("mouseout",function (e) {
            mar_right.continue();
        });
    });
</script>
</body>
</html> 




演示地址