jQuery插件实现无缝滚动特效


Posted in Javascript onNovember 24, 2015

首先来看下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 来查看)。

插件的实现代码:

(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插件实现无缝滚动特效

以上就是jQuery插件实现无缝滚动特效,效果实现有些简陋,不是很美观,但是方法是正确的,希望大家自己在此基础上进行美化。

Javascript 相关文章推荐
jQuery Selector选择器小结
May 06 Javascript
node.js中的fs.readFileSync方法使用说明
Dec 15 Javascript
使用javaScript动态加载Js文件和Css文件
Oct 24 Javascript
关于在Servelet中如何获取当前时间的操作方法
Jun 28 Javascript
jQuery EasyUI datagrid在翻页以后仍能记录被选中行的实现代码
Aug 15 Javascript
微信小程序 Template详解及简单实例
Jan 05 Javascript
BootStrap 图片样式、辅助类样式和CSS组件的实例详解
Jan 20 Javascript
vue实现个人信息查看和密码修改功能
May 06 Javascript
微信小程序实时聊天WebSocket
Jul 05 Javascript
JS实现判断有效的数独算法示例
Feb 25 Javascript
详解 微信小程序开发框架(MINA)
May 17 Javascript
vue指令v-html使用过滤器filters功能实例
Oct 25 Javascript
Jquery ajax加载等待执行结束再继续执行下面代码操作
Nov 24 #Javascript
谈谈encodeURI和encodeURIComponent以及escape的区别与应用
Nov 24 #Javascript
javascript实现加载xml文件的方法
Nov 24 #Javascript
jQuery 1.9.1源码分析系列(十)事件系统之主动触发事件和模拟冒泡处理
Nov 24 #Javascript
JavaScript转换与解析JSON方法实例详解
Nov 24 #Javascript
jQuery实现带分组数据的Table表头排序实例分析
Nov 24 #Javascript
JS数组排序技巧汇总(冒泡、sort、快速、希尔等排序)
Nov 24 #Javascript
You might like
PHP 网络开发详解之远程文件包含漏洞
2010/04/25 PHP
Notice: Trying to get property of non-object problem(PHP)解决办法
2012/03/11 PHP
php连接odbc数据源并保存与查询数据的方法
2014/12/24 PHP
php实现概率性随机抽奖代码
2016/01/02 PHP
Laravel 5.4重新登录实现跳转到登录前页面的原理和方法
2017/07/13 PHP
PHP中number_format()函数的用法讲解
2019/04/08 PHP
HTML页面滚动时获取离页面顶部的距离2种实现方法
2013/09/05 Javascript
javascript获取隐藏元素(display:none)的高度和宽度的方法
2014/06/06 Javascript
ext combobox动态加载数据库数据(附前后台)
2014/06/17 Javascript
简介BootStrap model弹出框的使用
2016/04/27 Javascript
用AngularJS来实现监察表单按钮的禁用效果
2016/11/02 Javascript
动态创建Angular组件实现popup弹窗功能
2017/09/15 Javascript
jquery实现侧边栏左右伸缩效果的示例
2017/12/19 jQuery
原生js+cookie实现购物车功能的方法分析
2017/12/21 Javascript
web前端页面生成exe可执行文件的方法
2018/02/08 Javascript
Babel 入门教程学习笔记
2018/06/13 Javascript
vue.js绑定事件监听器示例【基于v-on事件绑定】
2018/07/07 Javascript
解决vue-cli脚手架打包后vendor文件过大的问题
2018/09/27 Javascript
vue数据操作之点击事件实现num加减功能示例
2019/01/19 Javascript
详解用场景去理解函数柯里化(入门篇)
2019/04/11 Javascript
微信小程序分包加载代码实现方法详解
2019/09/23 Javascript
python实现查询IP地址所在地
2015/03/29 Python
Python 将pdf转成图片的方法
2018/04/23 Python
python八皇后问题的解决方法
2018/09/27 Python
python射线法判断一个点在图形区域内外
2019/06/28 Python
TensorFlow——Checkpoint为模型添加检查点的实例
2020/01/21 Python
Html5内唤醒百度、高德APP的实现示例
2019/05/20 HTML / CSS
白兰氏健康Mall:BRAND’S
2017/11/13 全球购物
伯利陶器:Burleigh Pottery
2018/01/03 全球购物
c++工程师面试问题
2013/08/04 面试题
超市仓管员岗位职责
2014/04/07 职场文书
婚前协议书怎么写
2014/04/15 职场文书
一般基层干部群众路线教育实践活动个人对照检查材料
2014/11/04 职场文书
太空授课观后感
2015/06/17 职场文书
2015年中学总务处工作总结
2015/07/22 职场文书
关于mysql中string和number的转换问题
2022/06/14 MySQL