基于编写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 相关文章推荐
利用webqq协议使用python登录qq发消息源码参考
Apr 08 Javascript
JQuery中SetTimeOut传参问题探讨
May 10 Javascript
原生js和jquery中有关透明度设置的相关问题
Jan 08 Javascript
深入学习JavaScript中的Rest参数和参数默认值
Jul 28 Javascript
html5+javascript实现简单上传的注意细节
Apr 18 Javascript
jQuery Checkbox 全选 反选的简单实例
Nov 29 Javascript
浅析JS中的 map, filter, some, every, forEach, for in, for of 用法总结
Mar 29 Javascript
jQuery实现动态生成表格并为行绑定单击变色动作的方法
Apr 17 jQuery
小发现之浅谈location.search与location.hash的问题
Jun 23 Javascript
js实现课堂随机点名系统
Nov 21 Javascript
JS实现可视化音频效果的实例代码
Jan 16 Javascript
vue 基于abstract 路由模式 实现页面内嵌的示例代码
Dec 14 Vue.js
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
完美实现GIF动画缩略图的php代码
2011/01/02 PHP
php中防止伪造跨站请求的小招式
2011/09/02 PHP
php出现web系统多域名登录失败的解决方法
2014/09/30 PHP
php使用pdo连接mssql server数据库实例
2014/12/25 PHP
完美利用Yii2微信后台开发的系列总结
2016/07/18 PHP
PHP中字符串长度的截取用法示例
2017/01/12 PHP
php实现微信公众号企业转账功能
2018/10/01 PHP
浅谈php的TS和NTS的区别
2019/03/13 PHP
PHP 并发场景的几种解决方案
2019/06/14 PHP
PHP实现批量修改文件名的方法示例
2019/09/18 PHP
TreeView 用法(有代码)(asp.net)
2011/07/15 Javascript
javascript禁用Tab键脚本实例
2013/11/22 Javascript
二叉树先序遍历的非递归算法具体实现
2014/01/09 Javascript
JQuery实现动态添加删除评论的方法
2015/05/18 Javascript
Node.js与Sails ~项目结构与Mvc实现及日志机制
2015/10/14 Javascript
require简单实现单页应用程序(SPA)
2016/07/12 Javascript
AngularJS入门教程之链接与图片模板详解
2016/08/19 Javascript
详解Javascript几种跨域方式总结
2017/02/27 Javascript
npm qs模块使用详解
2020/02/07 Javascript
Angular8 简单表单验证的实现示例
2020/06/03 Javascript
Vue 样式切换及三元判断样式关联操作
2020/08/09 Javascript
python开发之基于thread线程搜索本地文件的方法
2015/11/11 Python
浅谈python for循环的巧妙运用(迭代、列表生成式)
2017/09/26 Python
python itchat实现调用微信接口的第三方模块方法
2019/06/11 Python
TensorFlow tf.nn.max_pool实现池化操作方式
2020/01/04 Python
异常和异常类的概念
2014/09/12 面试题
物流合作计划书
2014/01/10 职场文书
七一党建活动方案
2014/01/28 职场文书
党校培训自我鉴定
2014/02/01 职场文书
《满井游记》教学反思
2014/02/26 职场文书
协议书范文
2015/01/27 职场文书
武当山导游词
2015/02/03 职场文书
幼儿园托班教育随笔
2015/08/14 职场文书
导游词之千岛湖
2019/09/23 职场文书
Go标准容器之Ring的使用说明
2021/05/05 Golang
详解 TypeScript 枚举类型
2021/11/02 Javascript