基于编写jQuery的无缝滚动插件


Posted in Javascript onAugust 02, 2014

首先来看下html骨架,如下:

<div class="box">
    <ul>
      <li>111</li>
      <li>222</li>
      <li>333</li>
    </ul>
</div>

结构简单明了,没什么说的。

讲下实现原理:

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

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

初始状态时,我们还要进行条件判断,判断是否进行滚动。即: 当 ul 长度小于 外层 box 长度时不进行滚动,反之则进行滚动。

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

之所以能实现无缝滚动,是因为每次滚动的长度刚好大于单个 li 的长度时,我们就将ul的第一个 li 移动到ul的最后,周而复始,无限循环(关于这

一点,你可以先不设置 overflow:hidden 来查看)。

讲个原理太TM考验我的表达能力了,希望我讲清楚了。

看插件的实现代码吧:

(function ($) {
  $.fn.Scroll = function (options) {
    //将当前上下文对象存入root
    var root = this;

    //默认配置
    var settings = {
      speed: 40,   //滚动速度,值越大速度越慢
      direction: "x" //滚动方向("x"或者"y" [x横向;y纵向])
    };

    //不为空,则合并参数
    if (options)
      $.extend(settings, options);


    var timer = [];   //计时器
    var marquee;    //滚动器(函数)
    var isRoll;     //判断是否滚动(函数)

    var _ul = $("> ul", root);     //ul标签
    var _li = $("> ul > li", root);   //li标签(集合)

    var li_num = _li.length;  //li标签个数
    var li_first = _li.first();  //获取单个li标签


    //判断为纵向还是横向,并进行相应操作
    if (settings.direction == "x") {


 



 var li_w = li_first.outerWidth(true); //单个li标签的宽度



 var ul_w = li_w * li_num; 


 //ul标签的宽度

      _ul.css({ width: ul_w }); //设置ul宽度

      marquee = function () {
        _ul.animate({ marginLeft: "-=1" }, 0, function () {
          var _mleft = Math.abs(parseInt($(this).css("margin-left")));
          if (_mleft > li_w) { //滚动长度一旦大于单个li的长度
            $("> li:first", $(this)).appendTo($(this)); //就把第一个li移到最后
            $(this).css("margin-left", 0); //滚动长度归0
          }
        });
      };
      //ul长度小于box长度时则不滚动,反之滚动
      isRoll = function (t) {
        if (ul_w <= root.width())
          clearInterval(t);
        else
          marquee();
      }
    }
    else {



 var li_h = li_first.outerHeight(true); //单个li标签的高度 



 var ul_h = li_h * li_num; //ul标签的高度

      _ul.css({ height: ul_h }); //设置ul高度

      marquee = function () {
        _ul.animate({ marginTop: "-=1" }, 0, function () {
          var _mtop = Math.abs(parseInt($(this).css("margin-top"))); //取绝对值
          if (_mtop > li_h) { 
            $("> li:first", $(this)).appendTo($(this));
            $(this).css("margin-top", 0);
          }
        });
      };
      //ul长度小于box长度时则不滚动,反之滚动
      isRoll = function (t) {
        if (ul_h <= root.height())
          clearInterval(t);
        else
          marquee();
      }
    }

    //遵循链式原则,并进行初始化
    return root.each(function (i) {
      //超出内容隐藏,防止用户没写overflow样式
      $(this).css({ overflow: "hidden" });

      timer[i] = setInterval(function () {
        isRoll(timer[i]);
      }, settings.speed);

      //鼠标进入停止滚动,离开继续滚动
      $(this).hover(function () {
        clearInterval(timer[i]);
      }, function () {
        timer[i] = setInterval(function () {
          isRoll(timer[i]);
        }, settings.speed);
      });

    });

  };
})(jQuery);

基本的代码说明注释写的很清楚了。下面对个别知识点作下讲解:

1.) var timer=[]; 之前timer并不是声明为数组类型的,是在我写demo的时候,由于页面同时存在两个无缝滚动的应用(为了演示横向和纵向), 出现了bug。

因为他们两个共用了一个timer计时器,当鼠标进入其中一个时,另一个的timer也被clear了。之后修改代码将其声明为数组对象,再通过root.each()就实
现了每个插件应用都有自己独立的timer计时器,互不干扰。也就是说此插件支持页面同时存在多个无缝滚动应用。

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

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

怎么样,是不是很强大啊!

下面给出DEMO代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style type="text/css">
  *{ margin:0; padding:0;}
  ul,ul li{ list-style:none;}  
  .wrap{ width:1000px; margin:50px auto;}  
  .box1,.box2,.box3{ overflow:hidden; float:left;border:1px solid gray;}  
  .box1{ width:200px; height:450px;}
  .box1 ul li{ width:200px; height:100px;} 
  .box2,.box3{ width:450px;height:150px; margin:40px;}
  .box2 ul li,.box3 ul li{ width:100px; height:150px; float:left;}
  
</style>
</head>

<body>
<div class="wrap">

  <div class="box1">
    <ul>
      <li>111纵向</li>
      <li>222纵向</li>
      <li>333纵向</li>
      <li>444纵向</li>
      <li>555纵向</li>
      <li>666纵向</li>
    </ul>
  </div>

  <div class="box2">
    <ul>
      <li>111横向</li>
      <li>222横向</li>
      <li>333横向</li>
      <li>444横向</li>
      <li>555横向</li>
      <li>666横向</li>
    </ul>
  </div> 
  
  <div class="box3">  
    <ul>
      <li>ul长度小于box长度,不滚动</li>
      <li>222横向</li>
      <li>333横向</li>      
    </ul>
  </div>  
</div>

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.similar.scroll.js"></script>
<script type="text/javascript">
  $(function () {
    //奇数背景设置为灰色
    $('.box1 li:even,.box2 li:even,.box3 li:even').css({ backgroundColor: "gray" });

    $(".box1").Scroll({ direction: "y" }); //设置为纵向滚动
    $(".box2").Scroll(); //默认横向滚动
    $(".box3").Scroll();
  });
</script>
</body>
</html>

效果图片:

基于编写jQuery的无缝滚动插件

演示因为样式问题,大家可以自行美化。

Javascript 相关文章推荐
jQuery 第二课 操作包装集元素代码
Mar 14 Javascript
JS Excel读取和写入操作(模板操作)实现代码
Apr 11 Javascript
一些老手都不一定知道的JavaScript技巧
May 06 Javascript
JQuery实现简单的服务器轮询效果实例
Mar 31 Javascript
第六章之辅组类与响应式工具
Apr 25 Javascript
AngularJS指令详解及示例代码
Aug 16 Javascript
BootStrap glyphicon图标无法显示的解决方法
Sep 06 Javascript
ion content 滚动到底部会遮住一部分视图的快速解决方法
Sep 06 Javascript
基于dataset的使用和图片延时加载的实现方法
Dec 11 Javascript
JavaScript实现全选取消效果
Dec 14 Javascript
详解vue.js根据不同环境(正式、测试)打包到不同目录
Jul 13 Javascript
vue 地区选择器v-distpicker的常用功能
Jul 23 Javascript
js使用removeChild方法动态删除div元素
Aug 01 #Javascript
js使用html()或text()方法获取设置p标签的显示的值
Aug 01 #Javascript
js中的getAttribute方法使用示例
Aug 01 #Javascript
jquery append()方法与html()方法的区别及使用介绍
Aug 01 #Javascript
JS中产生20位随机数以0-9为例也可以是a-z A-Z
Aug 01 #Javascript
js控制再次点击按钮之间的间隔时间可防止重复提交
Aug 01 #Javascript
批量修改标签css样式以input标签为例
Jul 31 #Javascript
You might like
漫威DC即将合作联动,而双方早已经秘密开始
2020/04/09 欧美动漫
虚拟主机中对PHP的特殊设置
2006/10/09 PHP
php的webservice的wsdl的XML无法显示问题的解决方法
2014/03/11 PHP
ThinkPHP中公共函数路径和配置项路径的映射分析
2014/11/22 PHP
php文件读取方法实例分析
2015/06/20 PHP
几种延迟加载JS代码的方法加快网页的访问速度
2013/10/12 Javascript
jquery ui bootstrap 实现自定义风格
2014/11/14 Javascript
JQuery中$.each 和$(selector).each()的区别详解
2015/03/13 Javascript
JavaScript操作DOM元素的childNodes和children区别
2015/04/01 Javascript
详解jQuery uploadify文件上传插件的使用方法
2016/12/16 Javascript
js自制图片放大镜功能
2017/01/24 Javascript
JavaScript实现简单的树形菜单效果
2017/06/23 Javascript
深入理解Vue 的条件渲染和列表渲染
2017/09/01 Javascript
Three.js利用性能插件stats实现性能监听的方法
2017/09/25 Javascript
JS原型继承四步曲及原型继承图一览
2017/11/28 Javascript
轻量级JS Cookie插件js-cookie的使用方法
2018/03/22 Javascript
vue使用v-for实现hover点击效果
2018/09/29 Javascript
axios异步提交表单数据的几种方法
2019/08/11 Javascript
JavaScript实现字符串与HTML格式相互转换
2020/03/17 Javascript
Python 用户登录验证的小例子
2013/03/06 Python
详解Python中内置的NotImplemented类型的用法
2015/03/31 Python
Python解析excel文件存入sqlite数据库的方法
2016/11/15 Python
python+opencv实现的简单人脸识别代码示例
2017/11/14 Python
Python 3.8新特征之asyncio REPL
2019/05/28 Python
在 Linux/Mac 下为Python函数添加超时时间的方法
2020/02/20 Python
HTML5 Canvas的性能提高技巧经验分享
2013/07/02 HTML / CSS
详解px单位html5响应式方案
2018/03/08 HTML / CSS
PHP面试题大全
2015/10/16 面试题
商务日语毕业生自荐信
2013/11/23 职场文书
致800米运动员广播稿
2014/02/16 职场文书
2014年度个人总结范文
2015/03/09 职场文书
求职信范文怎么写
2015/03/19 职场文书
2015年医院科室工作总结范文
2015/05/26 职场文书
千万级用户系统SQL调优实战分享
2022/03/03 MySQL
golang的文件创建及读写操作
2022/04/14 Golang
介绍一下28个JS常用数组方法
2022/05/06 Javascript