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 代码也可以变得优美的实现方法
Jun 22 Javascript
《JavaScript高级程序设计》阅读笔记(三) ECMAScript中的引用类型
Feb 27 Javascript
jQuery点击后一组图片左右滑动的实现代码
Aug 16 Javascript
js 文本滚动效果的实例代码
Aug 17 Javascript
jquery实现按Enter键触发事件示例
Sep 10 Javascript
node.js中的fs.symlinkSync方法使用说明
Dec 15 Javascript
angularJS Provider、factory、service详解及实例代码
Sep 21 Javascript
Bootstrap Img 图片样式(推荐)
Dec 13 Javascript
Vue.js基础知识小结
Jan 13 Javascript
react 生命周期实例分析
May 18 Javascript
基于VUE实现简单的学生信息管理系统
Jan 13 Vue.js
解决Vue+SpringBoot+Shiro跨域问题
Jun 09 Vue.js
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
ftp类(myftp.php)
2006/10/09 PHP
PHP调用三种数据库的方法(3)
2006/10/09 PHP
用session做客户验证时的注意事项
2006/10/09 PHP
利用php递归实现无限分类 格式化数组的详解
2013/06/08 PHP
php curl模拟post提交数据示例
2013/12/31 PHP
PHP中strtr字符串替换用法详解
2014/11/26 PHP
Yii2框架中使用PHPExcel导出Excel文件的示例
2017/08/09 PHP
PHP关于foreach复制知识点总结
2019/01/28 PHP
laravel5.6中的外键约束示例
2019/10/23 PHP
jquery 判断滚动条到达了底部和顶端的方法
2014/04/02 Javascript
JavaScript sub方法入门实例(把字符串显示为下标)
2014/10/17 Javascript
avalonjs制作响应式瀑布流特效
2015/05/06 Javascript
深入分析jsonp协议原理
2015/09/26 Javascript
jQuery获取当前点击的对象元素(实现代码)
2016/05/19 Javascript
bootstrap fileinput完整实例分享
2016/11/08 Javascript
详解浏览器渲染页面过程
2017/02/09 Javascript
Bootstrap弹出框之自定义悬停框标题、内容和样式示例代码
2017/07/11 Javascript
详解JS中统计函数执行次数与执行时间
2018/09/04 Javascript
Vue中对拿到的数据进行A-Z排序的实例
2018/09/25 Javascript
js实现图片上传到服务器和回显
2020/01/19 Javascript
vue+springboot图片上传和显示的示例代码
2020/02/14 Javascript
Django框架中的对象列表视图使用示例
2015/07/21 Python
Python针对给定字符串求解所有子序列是否为回文序列的方法
2018/04/21 Python
Python字典创建 遍历 添加等实用基础操作技巧
2018/09/13 Python
Python Django框架url反向解析实现动态生成对应的url链接示例
2019/10/18 Python
Python 解决火狐浏览器不弹出下载框直接下载的问题
2020/03/09 Python
基于Python计算圆周率pi代码实例
2020/03/25 Python
John Hardy官方网站:手工设计首饰的奢侈品牌
2017/07/05 全球购物
美国按摩椅批发网站:Titan Chair
2018/12/27 全球购物
会计专业应届生求职信
2013/11/24 职场文书
餐厅经理岗位职责范本
2014/02/17 职场文书
逃课打麻将检讨书
2014/10/05 职场文书
大学生创业事迹材料
2014/12/30 职场文书
市语委办2016年第十九届“推普周”活动总结
2016/04/05 职场文书
js中Map和Set的用法及区别实例详解
2022/02/15 Javascript
DE1107机评
2022/04/05 无线电