基于编写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 相关文章推荐
URI、URL和URN之间的区别与联系
Dec 20 Javascript
突发奇想的一个jquery插件
Nov 19 Javascript
对Jquery中的ajax再封装,简化操作示例
Feb 12 Javascript
网站接入QQ登录的两种方法
Jul 22 Javascript
jquery用offset()方法获得元素的xy坐标
Sep 06 Javascript
JavaScript更改字符串的大小写
May 07 Javascript
解决同一页面中两个iframe互相调用jquery,js函数的方法
Dec 12 Javascript
微信小程序 密码输入(源码下载)
Jun 27 Javascript
Rollup处理并打包JS文件项目实例代码
May 31 Javascript
解决vue单页路由跳转后scrollTop的问题
Sep 03 Javascript
vue实现移动端悬浮窗效果
Dec 01 Javascript
微信小程序实现圆形进度条动画
Nov 18 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
提升PHP执行速度全攻略(下)
2006/10/09 PHP
用PHP和ACCESS写聊天室(十)
2006/10/09 PHP
php 无限级 SelectTree 类
2009/05/19 PHP
php HandlerSocket的使用
2011/05/02 PHP
PHP中其实也可以用方法链
2011/11/10 PHP
Smarty模板简单配置与使用方法示例
2016/05/23 PHP
PHP基于堆栈实现的高级计算器功能示例
2017/09/15 PHP
php5.6.x到php7.0.x特性小结
2019/08/17 PHP
JS获取url链接字符串 location.href
2013/12/23 Javascript
JS判断文本框内容改变事件的简单实例
2014/03/07 Javascript
PHP+MySQL+jQuery随意拖动层并即时保存拖动位置实例讲解
2015/10/09 Javascript
JavaScript中Number对象的toFixed() 方法详解
2016/09/02 Javascript
Angular2入门教程之模块和组件详解
2017/05/28 Javascript
bootstrap精简教程_动力节点Java学院整理
2017/07/14 Javascript
详解React Native顶|底部导航使用小技巧
2017/09/14 Javascript
详谈commonjs模块与es6模块的区别
2017/10/18 Javascript
深入理解js A*寻路算法原理与具体实现过程
2018/12/13 Javascript
PWA介绍及快速上手搭建一个PWA应用的方法
2019/01/27 Javascript
JavaScript数组去重的几种方法
2019/04/07 Javascript
IntelliJ IDEA编辑器配置vue高亮显示
2019/09/26 Javascript
从0到1学习JavaScript编写贪吃蛇游戏
2020/07/28 Javascript
在Django中创建动态视图的教程
2015/07/15 Python
CentOS下Python3的安装及创建虚拟环境的方法
2018/11/28 Python
Python学习笔记之函数的参数和返回值的使用
2019/11/20 Python
Pytorch学习之torch用法----比较操作(Comparison Ops)
2020/06/28 Python
vscode调试django项目的方法
2020/08/06 Python
CSS3打造百度贴吧的3D翻牌效果示例
2017/01/04 HTML / CSS
HTML5新增的Css选择器、伪类介绍
2013/08/07 HTML / CSS
安全协议书范本
2014/04/21 职场文书
我为党旗添光彩演讲稿
2014/09/10 职场文书
乡镇干部个人对照检查材料思想汇报(原创篇)
2014/09/28 职场文书
房屋产权证明书
2014/10/15 职场文书
辞职信模板(中英文版)
2015/02/27 职场文书
廉洁自律承诺书范文
2015/04/28 职场文书
2016党员干部反腐倡廉心得体会
2016/01/13 职场文书
详解Python requests模块
2021/06/21 Python