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 相关文章推荐
一行代码实现纯数据json对象的深度克隆实现思路
Jan 09 Javascript
json数据处理技巧(字段带空格、增加字段、排序等等)
Jun 14 Javascript
实现51Map地图接口(示例代码)
Nov 22 Javascript
关于onchange事件在IE和FF下的表现及解决方法
Mar 08 Javascript
一个html5播放视频的video控件只支持android的默认格式mp4和3gp
May 08 Javascript
react.js 父子组件数据绑定实时通讯的示例代码
Sep 25 Javascript
vue实现裁切图片同时实现放大、缩小、旋转功能
Mar 02 Javascript
js比较两个单独的数组或对象是否相等的实例代码
Apr 28 Javascript
使用react context 实现vue插槽slot功能
Jul 18 Javascript
Angular8基础应用之表单及其验证
Aug 11 Javascript
整理 node-sass 安装失败的原因及解决办法(小结)
Feb 19 Javascript
分享一个vue实现的记事本功能案例
Apr 11 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
压力如何影响浓缩咖啡品质
2021/03/03 咖啡文化
一个简单的PHP投票程序源码
2007/03/11 PHP
mac下使用brew配置环境的步骤分享
2011/05/23 PHP
Laravel框架路由配置总结、设置技巧大全
2014/09/03 PHP
PHP实现二维数组按某列进行排序的方法
2016/11/18 PHP
PHP addslashes()函数讲解
2019/02/03 PHP
PHP safe_mode开启对于PHP系统函数有什么影响
2020/11/10 PHP
js 三级关联菜单效果实例
2013/08/13 Javascript
详解jquery uploadify 上传文件
2013/11/09 Javascript
利用jQuery简单实现产品展示图片左右滚动功能(示例代码)
2014/01/02 Javascript
基于JavaScript实现仿京东图片轮播效果
2015/11/06 Javascript
详解JavaScript函数
2015/12/01 Javascript
Angular.JS学习之依赖注入$injector详析
2016/10/20 Javascript
vue使用监听实现全选反选功能
2018/07/06 Javascript
vue中动态添加class类名的方法
2018/09/05 Javascript
Vue中对拿到的数据进行A-Z排序的实例
2018/09/25 Javascript
详解vue 动态加载并注册组件且通过 render动态创建该组件
2019/05/30 Javascript
javascript设计模式 ? 外观模式原理与用法实例分析
2020/04/15 Javascript
ant design vue中日期选择框混合时间选择器的用法说明
2020/10/27 Javascript
Vue实现Header渐隐渐现效果的实例代码
2020/11/05 Javascript
[02:23]DOTA2英雄基础教程 幻影长矛手
2013/12/09 DOTA
Python while、for、生成器、列表推导等语句的执行效率测试
2015/06/03 Python
Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息示例
2018/07/18 Python
Python编程深度学习绘图库之matplotlib
2018/12/28 Python
PyQt QListWidget修改列表项item的行高方法
2019/06/20 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
2020/06/08 Python
python小技巧——将变量保存在本地及读取
2020/11/13 Python
竞选班干部的演讲稿
2014/04/24 职场文书
关于祖国的演讲稿
2014/05/04 职场文书
2014年行政后勤工作总结
2014/12/06 职场文书
2015新年寄语(一句话)
2014/12/08 职场文书
教师节老师寄语
2015/05/28 职场文书
初婚未育证明样本
2015/06/18 职场文书
宣传稿格式范文
2015/07/23 职场文书
Spring Data JPA的Audit功能审计数据库的变更
2021/06/26 Java/Android
Python Django / Flask如何使用Elasticsearch
2022/04/19 Python