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 相关文章推荐
javascript showModalDialog 内跳转页面的问题
Nov 25 Javascript
javascript 学习笔记(六)浏览器类型及版本信息检测代码
Apr 08 Javascript
javascript之典型高阶函数应用介绍二
Jan 10 Javascript
用JS提交参数创建form表单在FireFox中遇到的问题
Jan 16 Javascript
jQuery实现自定义checkbox和radio样式
Jul 13 Javascript
jquery控制显示服务器生成的图片流
Aug 04 Javascript
跟我学习javascript的严格模式
Nov 16 Javascript
JavaScript如何禁止Backspace键
Dec 02 Javascript
理解javascript中try...catch...finally
Dec 25 Javascript
如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)
Feb 23 Javascript
Angular.JS学习之依赖注入$injector详析
Oct 20 Javascript
react-native使用leanclound消息推送的方法
Aug 06 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 数组的指针操作实现代码
2011/02/08 PHP
PHP+MySQL删除操作实例
2015/01/21 PHP
php和redis实现秒杀活动的流程
2019/07/17 PHP
浅析PHP中的 inet_pton 网络函数
2019/12/16 PHP
Javascript实现的分页函数
2006/12/22 Javascript
Track Image Loading效果代码分析
2007/08/13 Javascript
JS中toFixed()方法引起的问题如何解决
2012/11/20 Javascript
纯JavaScript实现HTML5 Canvas六种特效滤镜示例
2013/06/28 Javascript
去掉gridPanel表头全选框的小例子
2013/07/18 Javascript
jquery实现textarea输入框限制字数的方法
2015/01/15 Javascript
jquery中EasyUI实现异步树
2015/03/01 Javascript
jQuery树插件zTree使用方法详解
2017/05/02 jQuery
JS 组件系列之Bootstrap Table的冻结列功能彻底解决高度问题
2017/06/30 Javascript
JavaScript递归算法生成树形菜单
2017/08/15 Javascript
vue-cli之router基本使用方法详解
2017/10/17 Javascript
浅谈angular2子组件的事件传递(任意组件事件传递)
2018/09/30 Javascript
js实现移动端轮播图
2020/12/21 Javascript
vue + element-ui的分页问题实现
2018/12/17 Javascript
JS使用对象的defineProperty进行变量监控操作示例
2019/02/02 Javascript
24个ES6方法解决JS实际开发问题(小结)
2020/05/31 Javascript
Python实现的监测服务器硬盘使用率脚本分享
2014/11/07 Python
django站点管理详解
2017/12/12 Python
Python实现k-means算法
2018/02/23 Python
springboot配置文件抽离 git管理统 配置中心详解
2019/09/02 Python
python3.8与pyinstaller冲突问题的快速解决方法
2020/01/16 Python
pytorch 查看cuda 版本方式
2020/06/23 Python
CSS3标注引用的出处和来源的方法
2020/02/25 HTML / CSS
HTML5播放实现rtmp流直播
2020/06/16 HTML / CSS
EVE LOM英国官网:全世界最好的洁面膏
2017/10/30 全球购物
AT&T Wireless:手机、无限数据计划和配件
2018/06/03 全球购物
android面试问题与答案
2016/12/27 面试题
大学毕业生的自我鉴定
2013/11/30 职场文书
小学生一分钟演讲稿
2014/08/26 职场文书
2014年工程工作总结
2014/11/25 职场文书
汽车车尾标语大全
2015/08/11 职场文书
如何判断pytorch是否支持GPU加速
2021/06/01 Python