zoukankan      html  css  js  c++  java
  • 自己编写jQuery插件 之 无缝滚动

    一. 效果图

     

    二. Html骨架结构

    <div class="box">
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
    </div>

    三. 原理讲解

    1. div.box是最外层盒子, 给它固定的宽高,记得给div.box添加一个 overflow:hidden 样式(超出的内容隐藏) ,因为滚动肯定会超出box的。

    2. 我们通过js控制 ul 标签的 margin 来实现滚动。横向滚动控制 margin-left, 纵向则控制 margin-top。

    3. 初始时,我们要进行条件判断,判断其是否应该滚动。即: 当 ul 宽度[横向](或高度[纵向])小于外层 div.box 时不进行滚动,反之则进行滚动。

    4. ul 的长度是通过计算得来的,即:ul里面单个 li 的长度乘以 li 的个数。ul_width = li_width * li_num。

    5. 之所以能实现无缝滚动,是因为每次滚动的长度刚好大于单个 li 的长度时,我们就将 ul 的第一个 li 移动到 ul 的最后,周而复始, 无限循环(关于这一点,你可以先不设置 overflow:hidden 来查看)。

    四. 插件实现代码

    (function ($) {
        $.fn.scroll = function (options) {
            
            var root = this,                //将当前上下文对象存入root
                timer = [],                 //计时器
                ulTag = $("> ul", root),    //ul标签
                liTag = $("> li", ulTag),   //li标签(集合)
                liNum = liTag.length,       //li标签个数
                liOne = liTag.first(),      //获取单个li标签
                marquee,                    //滚动器(函数)
                liUnit,                     //单个li的宽或者高(横向时为宽,纵向时为高)
                ulUnit,                     //ul的宽或者高(横向时为宽,纵向时为高)
                limit,                      //root的宽或者高(横向时为宽,纵向时为高)
                cssName,                    //样式名称(横向时为margin-left,纵向时为margin-top)
                effect;                     //动画效果(横向时为marginLeft,纵向时为marginTop)
    
            //默认配置
            var settings = {
                speed: 40,      //滚动速度,值越大速度越慢
                direction: "x"  //滚动方向("x"或者"y" [x横向;y纵向])
            };
    
            //不为空,则合并参数
            if (options){
                $.extend(settings, options);
            }
    
            //横向
            if(settings.direction === "x"){
                limit = root.width();
                cssName = "margin-left";
                liUnit = liOne.outerWidth(true);
                ulUnit = liUnit * liNum;            //单个li的宽 * li的个数 = ul的宽度
                effect = { marginLeft : "-=1" };
    
                ulTag.css({  ulUnit });       //设置ul的宽
            }
    
            //纵向
            if(settings.direction === "y"){
                limit = root.height();
                cssName = "margin-top";
                liUnit = liOne.outerHeight(true);
                ulUnit = liUnit * liNum;            //单个li的高 * li的个数 = ul的高度
                effect = { marginTop : "-=1" };
               
                ulTag.css({ height: ulUnit });      //设置ul的高
            }
    
            marquee = function(){
                ulTag.animate(effect, 0, function(){
    
                    //ul滚动的距离,取绝对值
                    var distance = Math.abs(parseInt($(this).css(cssName),10));
    
                    //如果滚动的距离一旦大于单个li的长度
                    if(distance > liUnit){
                        $("> li:first", $(this)).appendTo($(this)); //就把第一个li移到最后
                        $(this).css(cssName, 0);                    //滚动长度归0
                    }
                });
            }
    
            //遵循链式原则,并进行初始化
            return root.each(function (i) {
    
                //只有当ul的长度大于root长度时才进行滚动
                if(ulUnit > limit){               
                    timer[i] = setInterval(marquee,settings.speed);
    
                    //鼠标进入停止滚动,离开继续滚动
                    $(this).hover(function () {
                        clearInterval(timer[i]);
                    }, function () {
                        timer[i] = setInterval(marquee,settings.speed);
                    });
                }
            });
    
        };
    })(jQuery);

    五. 关于代码的讲解

    基本的说明注释写的很清楚了,下面针对个别知识点作下讲解

    1. var timer=[] 之前 timer 并不是声明的数组类型,是在我写 demo 的时候,由于页面同时存在两个无缝滚动的应用(为了演示横向和纵向),出现了bug。因为它们两个共用了一个 timer 计时器,当鼠标进入其中一个时,另一个的 timer 也被 clear 了。之后修改代码将其声明为数组对象,再通过 root.each() 就实现了每个插件应用都有自己独立的 timer 计时器,互不干扰。也就是说此插件支持页面中同时存在多个无缝滚动的应用。

    2. outerWidth() / outerHeight() 函数。 这个函数比较强大,它获取的不仅仅是元素的宽度 / 高度,

    实际上 outerWidth() = width + borderLeft + borderRight + marginLeft + marginRight; 当它设置为 true 后,即:outerWidth(true),它也会将 padding 计算进来。

    outerWidth(true) = width + borderLeft + borderRight + marginLeft + marginRight + paddingLeft + paddingRight;

    六. 一个完整的示例,效果和上面的效果图一模一样

    1. Html

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>jQuery无限滚动插件</title>
        <link rel="stylesheet" type="text/css" href="css/style.css" />  <!-- 此处引用的为下面的 Css 代码 -->
    </head>
    <body>
        <h3 class="title">jQuery无限滚动插件</h3>
    
        <div class="xbox">
            <ul>
                <li><a href="#">x</a></li>
                <li><a href="#">1</a></li>
                <li><a href="#">2</a></li>
                <li><a href="#">3</a></li>
                <li><a href="#">4</a></li>
                <li><a href="#">5</a></li>
            </ul>
        </div>
    
        <div class="ybox">
            <ul>
                <li><a href="#">y</a></li>
                <li><a href="#">1</a></li>
                <li><a href="#">2</a></li>
                <li><a href="#">3</a></li>
                <li><a href="#">4</a></li>
                <li><a href="#">5</a></li>
            </ul>
        </div>
    
    <script type="text/javascript" src="script/jquery.min.js"></script>
    <script type="text/javascript" src="script/jquery.similar.scroll.js"></script> <!-- 此处引用的为上面的插件实现代码 -->
    <script type="text/javascript">
        $(function () {        
            $(".xbox").scroll(); //默认横向滚动
            $(".ybox").scroll({ direction: "y" }); //设置为纵向滚动
        });
    </script>
    </body>
    </html>

    2. Css

    body{
        font-family: Arial;
    }
    body,ul,li{ 
        margin:0; 
        padding:0;
    }
    ul,li,img{
        list-style: none;
    }
    .title{
        width: 100%;
        text-align: center;
    }
    .xbox,.ybox{
        overflow: hidden;
        margin: 20px auto;
        padding: 5px;
        border: 2px solid #DDD;
    }
    .xbox{
        width: 500px;
        height: 50px;
    }
    .xbox ul li{
        float: left;
        margin-right: 5px;
    }
    .xbox ul li a, .ybox ul li a{
        display: block;
        width:100px;
        height: 50px;
        box-shadow: 0 0 40px rgba(0,0,0,0.2) inset;
        text-decoration: none;
        color: gray;
        font-size: 20px;
        text-align: center;
        line-height: 50px;
    }
    .ybox{
        width: 100px;
        height: 250px;
    }
    .ybox ul li{
        margin-bottom: 5px;
    }
  • 相关阅读:
    suse12安装详解
    Centos7上部署openstack mitaka配置详解(将疑难点都进行划分)
    菜鸟帮你跳过openstack配置过程中的坑[文末新添加福利]
    openstack中dashboard页面RuntimeError: Unable to create a new session key. It is likely that the cache is unavailable.
    Multiple network matches found for name 'selfservice', use an ID to be more specific.报错
    查看 SELinux状态及关闭SELinux
    SELinux深入理解
    IP地址、子网掩码、网络号、主机号、网络地址、主机地址
    Oracle job procedure 存储过程定时任务
    POI文件导出至EXCEL,并弹出下载框
  • 原文地址:https://www.cnblogs.com/similar/p/5904599.html
Copyright © 2011-2022 走看看