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 相关文章推荐
csdn 批量接受好友邀请
Feb 19 Javascript
JS子父窗口互相操作取值赋值的方法介绍
May 11 Javascript
Blocksit插件实现瀑布流数据无限( 异步)加载
Jun 20 Javascript
javascript获得当前的信息的一些常用命令
Feb 25 Javascript
JavaScript DOM 学习总结(五)
Nov 24 Javascript
JavaScript ParseFloat()方法
Dec 18 Javascript
Angular实现可删除并计算总金额的购物车功能示例
Dec 26 Javascript
从0到1构建vueSSR项目之路由的构建
Mar 07 Javascript
vue使用localStorage保存登录信息 适用于移动端、PC端
May 27 Javascript
javascript+css实现俄罗斯方块小游戏
Jun 28 Javascript
OpenLayers3实现图层控件功能
Sep 25 Javascript
vue3.0实现点击切换验证码(组件)及校验
Nov 18 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
PHP 替换模板变量实现步骤
2009/08/24 PHP
Yii框架关联查询with用法分析
2014/12/02 PHP
详解PHP中的null合并运算符
2015/12/30 PHP
PHP错误处理函数register_shutdown_function使用示例
2017/07/03 PHP
实例讲解PHP表单处理
2019/02/15 PHP
用javascript来实现动画导航效果的代码
2007/12/16 Javascript
斜45度寻路实现函数
2009/08/20 Javascript
javascript利用初始化数据装配模版的实现代码
2010/11/17 Javascript
js监听键盘事件示例代码
2013/07/26 Javascript
jquery使用ajax实现微信自动回复插件
2014/04/28 Javascript
jQuery动画效果图片轮播特效
2016/01/12 Javascript
AngularJS入门教程之AngularJS指令
2016/04/18 Javascript
小白谈谈对JS原型链的理解
2016/05/03 Javascript
Three.js学习之文字形状及自定义形状
2016/08/01 Javascript
常用的几个JQuery代码片段
2017/03/13 Javascript
vue实现验证码输入框组件
2017/12/14 Javascript
JavaScript设计模式之代理模式实例分析
2019/01/16 Javascript
微信小程序 flexbox layout快速实现基本布局的解决方案
2020/03/24 Javascript
Python实现并行抓取整站40万条房价数据(可更换抓取城市)
2016/12/14 Python
Python中矩阵库Numpy基本操作详解
2017/11/21 Python
Flask核心机制之上下文源码剖析
2018/12/25 Python
Python判断对象是否相等及eq函数的讲解
2019/02/25 Python
详解Python图像处理库Pillow常用使用方法
2019/09/02 Python
python如何爬取网页中的文字
2020/07/28 Python
Python爬虫之Selenium中frame/iframe表单嵌套页面
2020/12/04 Python
Python绘制K线图之可视化神器pyecharts的使用
2021/03/02 Python
HTML5中drawImage用法分析
2014/12/01 HTML / CSS
怎样声明接口
2014/09/19 面试题
请假条范文大全
2014/04/10 职场文书
支部书记四风问题自我剖析材料
2014/09/29 职场文书
经费申请报告
2015/05/15 职场文书
《叶问2》观后感
2015/06/15 职场文书
2016党校学习心得体会
2016/01/07 职场文书
详解Django的MVT设计模式
2021/04/29 Python
vue-router中hash模式与history模式的区别
2021/06/23 Vue.js
sql注入报错之注入原理实例解析
2022/06/10 MySQL