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({ width: 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;
}

原文链接:自己编写jQuery插件 之 无缝滚动

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值