YAOHAIXIAO.COM

HTML(5),CSS(3),JavaScript,DOM,Ajax,JSON,Front-end technologies & Yaohaixiao

热门标签:JavaScript Performance 前端开发 前端性能优化 原创

Rss

Home » Downloads » JScroller – jQuery 无缝循环滚动插件

JScroller – jQuery 无缝循环滚动插件

程序简介:

JScroller 无缝循环滚动特效应该是经常用到的一个实用的效果,JScroller 程序的原型是基于 YAHOO 图片的 scrollnews.js,现在用 jQuery 重构了程序。效果图如下:

// 横行滚动调用代码
(function(){
	$('#scroll-h').scroller({
		scroller: $('#scroll-h-con'),
		repeaterTag: 'ul',
		itemTag: '.scroll-item',
		speed: 10,
		direction: 'H'
	}); 
})();
// 纵行滚动调用代码
(function(){
	$('#scroll-v').scroller({
		scroller: $('#scroll-v-con'),
		repeaterTag: 'ul',
		itemTag: '.scroll-item',
		speed: 50
	});
})();

下载地址:scrollnews.zip

程序特点:

  • 支持横向和纵向连续滚动
  • 滚动采用了缓动算法,滚动效果连贯自然
  • 支持自定义滚动时间间隔
  • 支持任意内容的连续滚动
  • 兼容主流浏览器(IE6~9、Firefox、Chrome、Safari、Opera)

程序 JavaScript 源代码

/**
 * 连续循环滚动特效
 * 
 * @auhtor Yaohaixiao
 * @version 1.3.1.10
 */
(function($){
	/**
	 * 滚动新闻的构造函数
	 * 
	 * @constructor JScroller
	 * @param {String|HTMLElement} config.root - 滚动区域的根节点
	 * @param {String|HTMLElement} config.scroller - 复制的滚动内容节点  
	 * @param {String} [config.repeaterTag] - 动态创建的克隆的滚动内容根元节点的 tagName (默认值:div)
	 * @param {String} [config.itemTag] - 滚动内容单个元素的 tagName (默认值:li)
	 * @param {String} [config.direction] - 滚动的方向:V - 纵向滚动 H - 横向滚动 (默认值:V)
	 * @param {Number} [config.unitTime] - 滚动一屏后,下一屏开始滚动的时间间隔 (默认值:4000 ms)
	 * @param {Number} [config.pauseTime] - 鼠标放到滚动内容上停止混动,鼠标离开后开始关东的等待时间 (默认值:2000)
	 */
	$.JScroller = function(config){
		// 配置项
		this.setting = {
			root: null,             
			scroller: null,         
			repeater: null,  // 复制的滚动内容节点 
			itemTag: '',
			repeaterTag: '', 
			direction: 'V',   
			unitTime: 4000,
			pauseTime: 2000,
			speed: 50,     
			items: null,     // 滚动内容中所有的单元节点
			length: 0,       // 单元节点的个数
			itemWidth: 0,    // 单元节点的宽度
			itemHeight: 0,   // 单元节点的高度
			width: 0,        // 滚动内容的宽度
			height: 0,       // 滚动内容的高度
			scrollValue: 0,  // 每次关东的 scrollTop 或者 scrollLeft 的值
			scrollWidth: 0,  // 横向滚动的距离
			scrollHeight: 0, // 纵向滚动的距离 
			timer: null,
			lastIndex: 0
		};
		
		// 合并配置项
		$.extend(this.setting, config);
		
		this.init();
		
		return this;
	};
	
	$.JScroller.prototype = {
		init: function(){
			var that = this, 
			    setting = this.setting, 
				root = $(setting.root), 
				scroller = $(setting.scroller), 
				itemTag = setting.itemTag ? setting.itemTag : 'li', 
				repeaterTag = setting.repeaterTag ? setting.repeaterTag : 'div', 
				direction = setting.direction.toUpperCase(), 
				repeater = null,
				items = null, 
				firstItem = null,
				itemWidth = 0, 
				itemHeight = 0, 
				width = 0, 
				height = 0, 
				length = 0;
				
			// 没有初始化必选项时,退出程序
			if(!root[0] || !scroller[0]){
				return false;
			}
			
			// 获得相关的初始化值
			items = setting.items = scroller.find(itemTag);
			firstItem = $(items[0]);
			length = setting.length = items.length;
			itemWidth = setting.itemWidth = firstItem.width();
			itemHeight = setting.itemHeight = firstItem.height();
			width = setting.width = itemWidth * length;
			height = setting.height = itemHeight * length;
			scrollHTML = scroller.html();
			
			// 定位滚动内容并设置宽度
			scroller.css({
				'position': 'absolute',
				'top': 0,
				'left': 0,
				'width': width + 'px'
			});
			
			// 创建滚动层的克隆元素
			repeater = setting.repeater = $('<' + repeaterTag + '></' + repeaterTag + '>').addClass(scroller.attr('class')).attr('id', root.attr('id') + '_copymsgid');
			
			// 根据滚动方向,定位复制层的位置
			if (direction === 'V') {
				repeater.css({
					'position': 'absolute',
					'top': height + 'px',
					'left': 0
				}).html(scrollHTML);
			}
			else {
				if (direction === 'H') {
					repeater.css({
						'position': 'absolute',
						'width': width + 'px',
						'top': 0,
						'left': width + 'px'
					}).html(scrollHTML);
				}
			}
			
			// 将复制层添加到滚动区域的根节点中
			root.append(repeater);
			
			// 绑定事件
			this.bind();
			
			// 设定定时器,创建循环滚动的动画
			setting.timer = setTimeout(function(){
				that.play.call(that);
			}, setting.pauseTime);
			
			return this;
		},
		/**
		 * 滚动的动画播放
		 * 
		 * @method play
		 */
		play: function(){
			var direction = this.setting.direction;
			
			// 释放定时器资源	
			this.stop();
			
			// 纵向滚动
			if (direction === 'V') {
				this.scrollTop();
			}
			else {
				if (direction === 'H') {
					this.scrollLeft();
				}
			}
			
			return this;
		},
		/**
		 * 停止滚动
		 * 
		 * @method stop
		 */
		stop: function(){
			var setting = this.setting;
			
			if (setting.timer) {
				clearTimeout(setting.timer);
				setting.timer = null;
			}
			
			return this;
		},
		/**
		 * 纵向向上滚动
		 * 
		 * @method scrollTop
		 */
		scrollTop: function(){
			var that = this, 
			    setting = this.setting, 
				root = $(setting.root),
				dist = 0, 
				direction = setting.direction.toUpperCase(), 
				itemWidth = setting.itemWidth, 
				itemHeight = setting.itemHeight;
			
			if (direction === 'V') {
				// 计算滚动的距离(高度)
				if ((itemHeight * setting.lastIndex - setting.scrollValue) <= 0) {
					// 一屏滚动完毕
					setting.scrollValue = 0;
				}
				else {
					// 一屏还没有滚动完
					dist = Math.ceil(((itemHeight * setting.lastIndex) - setting.scrollValue) / 10);
					setting.scrollValue += dist;
					setting.scrollHeight += dist;
				}
				
				// 滚动内容
				root.scrollTop(setting.scrollValue);
				
				// 计算滚动了几屏了
				if (setting.scrollHeight % itemHeight === 0) {
					setting.lastIndex += 1;
					
					// 整个内容都滚动显示完毕
					if (setting.lastIndex === (setting.length + 1)) {
						setting.lastIndex = 0;
					}
					
					// 滚动被暂停了
					if (!setting.lastIndex) {
						setting.timer = setTimeout(function(){
							that.play.call(that);
						}, setting.pauseTime);
					}
					else {
						// 滚完了一屏
						setting.timer = setTimeout(function(){
							that.play.call(that);
						}, setting.unitTime);
					}
				}
				else {
					// 正常的滚动过程中
					setting.timer = setTimeout(function(){
						that.play.call(that);
					}, setting.speed);
				}
			}
			
			return this;
		},
		/**
		 * 横向向左滚动
		 * 
		 * @method scrollLeft
		 */
		scrollLeft: function(){
			var that = this, 
			    setting = this.setting, 
				root = $(setting.root),
				dist = 0, 
				direction = setting.direction.toUpperCase(), 
				itemWidth = setting.itemWidth, 
				itemHeight = setting.itemHeight;

			if (direction === 'H') {
				// 计算滚动的距离(高度)
				if ((itemWidth * setting.lastIndex) - setting.scrollValue <= 0) {
					// 一屏滚动完毕
					setting.scrollValue = 0;
				}
				else {
					// 一屏还没有滚动完
					dist = Math.ceil(((itemWidth * setting.lastIndex) - setting.scrollValue) / 10);
					setting.scrollValue += dist;
					setting.scrollWidth += dist;
				}
				
				// 滚动内容
				root.scrollLeft(setting.scrollValue);
				
				// 计算滚动了几屏了
				if (setting.scrollWidth % itemWidth === 0) {
					setting.lastIndex += 1;
					
					// 整个内容都滚动显示完毕
					if (setting.lastIndex === (setting.length + 1)) {
						setting.lastIndex = 0;
					}
					
					// 滚动被暂停了
					if (!setting.lastIndex) {
						setting.timer = setTimeout(function(){
							that.play.call(that);
						}, setting.pauseTime);
					}
					else {
						// 滚完了一屏
						setting.timer = setTimeout(function(){
							that.play.call(that);
						}, setting.unitTime);
					}
				}
				else {
					// 正常的滚动过程中
					setting.timer = setTimeout(function(){
						that.play.call(that);
					}, setting.speed);
				}
			}
			
			return this;
		},
		/**
		 * 绑定滚动区域鼠标划过和离开时停止滚动和继续滚动
		 * 
		 * @method bind 
		 */
		bind: function(){
			var that = this, 
			    setting = this.setting, 
				root = $(setting.root);
			
			if(!root[0]){
				return false;
			}
			
			// 鼠标放到滚动区域时,停止滚动
			root.mouseover(function(){
				that.stop.call(that);
			});
			
			// 鼠标离开滚动区域(2秒)时,继续滚动
			root.mouseout(function(evt){
				setting.timer = setTimeout(function(){
					that.play.call(that);
				}, setting.pauseTime);
			});
			
			return this;
		}
	};
	
	$.fn.extend({
		scroller: function(config){
			config.root = $(this);
			
			new $.JScroller(config);
		}
	});
})(jQuery);

声明:本文采用BY-NC-SA协议进行授权。转载请注明转自:JScroller – jQuery 无缝循环滚动插件

« »

1 条评论

  • 4年多前从YAHOO扣的代码,做了少许调整,兼容性还是不错的,只是现在看来,代码的封装做得不是很好。

    所以这里给出的DEMO是我用jQuery重写过,代码可读性和效率应该是更好了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(Spamcheck Enabled)