YAOHAIXIAO.COM

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

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

Rss

Home » Downloads » tabsView – jQuery 插件

tabsView – jQuery 插件

程序简介:

tabsView是用 jQuery 重写了我之前的 YTabs 控件,基本上把 YTabs 的所有功能都实现了,还添加了 AajaxTab 的缓存。以前在阿里巴巴都是用的 YUI 开发,jQuery用的并不多,写这个主要是自己也在学习 jQuery。喜欢用 jQuery 的朋友可以用我这款插件,兼容性很好,调用也挺方便的。

自动切换的排行榜

带缩略图的横向循环滚动图片新闻

自定义默认显示项

带下拉菜单的tab导航

英文字母索引下拉菜单

自动切换带缓存的Ajax导航

数字索引自动循环滚动的图片新闻

下载地址:tabsView.zip

程序特点:

  1. 支持自动切换,可以透明和滚动过渡
  2. 支持横向和纵向连续滚动过度效果
  3. 支持循环不间断滚动
  4. 滚动采用了缓动算法,滚动效果连贯自然
  5. 自定义滚动时间间隔
  6. 自定事件类型
  7. 自定默认显示项
  8. 支持Ajax加载(支持html,JSON格式数据)
  9. 支持是否缓存Ajax数据
  10. 丰富的示例,几乎包括所有常用交互方式
  11. 自带默认的CSS框架,扩展性好
  12. 兼容主流浏览器(IE6~9、Firefox、Chrome、Safari、Opera)

程序 JavaScript 代码:

/**
 * @author yaohaixiao
 * @update 2012/02/21
 */
(function($){
	/**
     * tabsView
     * @constructor tabsView
     * @param {NodeList|String} config.tabs
     * @param {NodeList|String} config.contents
     * @param {Element} [config.root]
     * @return {Object} $.tabsView
     */
    $.tabsView = function(config){
		// 配置信息
		this.setting = {
			root: null,
			tabs: null,
			contents: null,
			hash: false,
			defaultIndex: 0,
			selectedClass: 'current',
			isFirstView: true,
			defaultData: '',
			lastIndex: 0,
			callback: null,
			hideAll: false,
			lastTab: null,
			lastContent: null,
			timer: null,
			auto: null,
			scroll: null,
			evtType: 'click',
			Ajax: null
		};
		
		// 合并配置信息
		$.extend(this.setting, config);
		
		// 初始化
		this.init();
		
		return this;
	};

    /**
     * tabsView 的公用方法
     */
    $.tabsView.prototype = {
        /**
         * 初始化 tabsView
         *
         * @method init
         * @return {Object} jQuery.tabsView
         */
	    init: function(){
			var tabsView = this, 
			    setting = this.setting, 
				root = $(setting.root), 
				tabs = null, 
				contents = null, 
				hashIndex = -1, 
				defaultIndex = 0, 
				lastIndex = setting.lastIndex, 
				isAuto = setting.auto, 
				isAjax = setting.Ajax, 
				isScroll = setting.scroll;
			
			// 如果设置了 tabsView 模块的根节点,则在根节点中搜索 tabs 和 contents
			// 这样避免遍历整个文档,加快搜索速度,提高性能
			if (root) {
				tabs = setting.tabs = root.find(setting.tabs).length > 0 ? root.find(setting.tabs) : root.find('li');
				
				contents = setting.contents = root.find(setting.contents).length > 0 ? root.find(setting.contents) : root.find('.tabs-post');
			}
			else {
				// 遍历整个文档,搜索 tabs 和 contents
				tabs = $(setting.tabs);
				contents = $(setting.contents);
			}
			
			// 获得默认显示项的索引值
			if (setting.hash) {
				// 根据 URL 获得 默认选中的 tab 索引值
				hashIndex = this.getHashIndex();
			}
			// 获得默认选中 tab 的索引值
			defaultIndex = setting.defaultIndex = hashIndex > -1 ? hashIndex : setting.defaultIndex;
			
			// 获得上次选中的 tab
			setting.lastTab = $(tabs[lastIndex]);
			
			// 如果是Ajax选项卡,需要缓存数据
			if (isAjax) {
				// 获得上次选中的 content
				// ajaxTab 导航时只有一个 content 容器
				setting.lastContent = $(contents[0]);
				
				// 创建 Ajax 缓存数据
				isAjax.cacheData = [];
				
				// 缓存默认显示的内容
				setting.defaultData = contents[0].innerHTML;
				
				// 设置的默认项是页面输出内容,这时才缓存默认的数据
				if (defaultIndex === lastIndex) {
					isAjax.cacheData[defaultIndex] = setting.defaultData;
				}
			}
			else {
				// 获得上次选中的 content
				setting.lastContent = $(contents[setting.lastIndex]);
			}
			
			// 如果设置了滚动切换
			if (isScroll) {
				// 获得纵向滚动一次的高度
				isScroll.itemHeight = $(contents[0]).height();
				
				// 获得横向滚动一次的高度
				isScroll.itemWidth = $(contents[0]).width();
			}
			
			// 如果设置了默认隐藏全部内容(下拉菜单效果)时
			if (setting.hideAll) {
				// 不需要设置默认显示项
				this.bind();
			}
			else {
				// 设置默认显示项
				this.setCurrent(defaultIndex).bind();
			}
			
			// 如果设置了自动切换
			if (isAuto) {
				// 开始自动切换,默认 4 秒后启动切换
				setting.timer = setTimeout(function(){
					tabsView.autoChange.call(tabsView);
				}, isAuto.speed);
			}
			
			return this;
		},
        /**
         * 绑定事件
         *
         * @method bind
         * @return {Object} jQuery.tabsView
         */
	    bind: function(){
			var tabsView = this, 
			    setting = this.setting, 
				contents = setting.contents, 
				selectedClass = setting.selectedClass,
				isAuto = setting.auto, 
				isHideAll = setting.hideAll, 
				evtType = setting.evtType;
			
			// 给每个 tab 绑定出发切换的事件
			setting.tabs.each(function(i, tab){
				// 支持TAB键切换
				if (tab.tagName.toLowerCase() === 'a') {
					$(tab).focusin(function(evt){
						tabsView.setCurrent(i);

						evt.preventDefault();
						evt.stopPropagation();
					});
				}
				else {
					if (tab.tagName.toLowerCase() === 'li') {
						$($(tab).find('a')[0]).focusin(function(evt){
							tabsView.setCurrent(i);

							evt.preventDefault();
							evt.stopPropagation();
						});
					}
				}
				
				$(tab)[evtType](function(evt){
					// 下拉菜单效果的时候,只要鼠标放到 tab 上面,就显示相应的内容
					if (isHideAll) {
						if (evtType.toLowerCase() === 'mouseover') {
							tabsView.setCurrent(i);
						}
					}
					else {
						// 点击非当前项才触发切换				
						if (i !== setting.lastIndex) {
							tabsView.setCurrent(i);
						}
					}
					
					evt.preventDefault();
					evt.stopPropagation();
				});
				
				// 如果设置了自动切换
				if (isAuto) {
					// 鼠标在 tab 上时,停止自动切换
					$(tab).mouseover(function(){
						if (setting.timer) {
							clearTimeout(setting.timer);
							setting.timer = null;
						}
					});
					
					// 鼠标离开 tab (默认 2 秒)后,重新开始自动切换
					$(tab).mouseout(function(evt){
						setting.timer = setTimeout(function(){
							tabsView.autoChange.call(tabsView);
						}, isAuto.speed / 2);
					});
					
					// 鼠标在 root 上时,停止自动切换
					$(contents[i]).mouseover(function(evt){
						if (setting.timer) {
							clearTimeout(setting.timer);
							setting.timer = null;
						}
					});
					
					// 鼠标离开 root (默认 2 秒)后,重新开始自动切换
					$(contents[i]).mouseout(function(evt){
						setting.timer = setTimeout(function(){
							tabsView.autoChange.call(tabsView);
						}, isAuto.speed / 2);
					});
				}
				else {
					// 如果设置了隐藏全部
					if (isHideAll) {
						$(tab).mouseout(function(evt){
							// 鼠标离开时回复标签未选中的样式
							$(tab).removeClass(selectedClass);
							
							// 鼠标离开时隐藏之前显示的内容
							$(setting.contents[i]).addClass('hide');
						});
					}
				}
			});
			
			return this;
		},
        /**
         * 设置选中项
         * @method setCuurent
         * @param {Number} tabIndex - 选中项在 tabs NodeList 中的索引值
         * @return {Object} jQuery.tabsView
         */
	    setCurrent: function(tabIndex){
		    var tabsView = this, 
				setting = this.setting, 
				tabs = setting.tabs,
			    contents = setting.contents, 
				selectedClass = setting.selectedClass,
			    curTab = $(tabs[tabIndex]), 
			    curContent = $(contents[tabIndex]),
			    isAjax = setting.Ajax,
			    isScroll = setting.scroll, 
			    isFade = setting.fade,
			    opacityVal = 1,
				callback = setting.callback,
			    timer = null,
                /**
                 * 透明隐藏过度特效
                 * 透明隐藏过度特效是上一个内容透明过度,
                 * 过度完了,显示当前的内容
                 *
                 * @method fadeIn
                 * @private
                 */
			    fadeIn = function(){
					// 释放 timer 的资源
					if (timer) {
						clearTimeout(timer);
						timer = null;
					}
					
					// 透明值递减
					opacityVal -= 0.05;
					
					// 透明到完全看不到了
					if (opacityVal < 0) {
						showCurContent();
						
						// 恢复上一项的透明值				
						$(setting.lastContent).css('opacity', 1);
						
						// 退出透明过度函数
						return false;
					}
					
					// 透明过度
					$(setting.lastContent).css('opacity', opacityVal);
					
					// 定时器
					timer = setTimeout(fadeIn, isFade.speed);
				},
			    showCurContent = function(){
					$(setting.lastContent).addClass('hide');
					curContent.removeClass('hide');
					setting.lastContent = curContent;
				},
			    direction = '',
			    isCycle = false;
		
		    // 设置上次选中的 tab 样式
		    $(setting.lastTab).removeClass(selectedClass);
		    // 设置当前的 tab 样式
		    curTab.addClass(selectedClass);
		
		    // 设置了滚动切换效果
		    if (isScroll) {
			    // 获得滚动方向:h - 纵向(默认);v - 横向
			    direction = (isScroll.direction || $(isScroll.body).attr('id').split('-')[1]) || 'h';
			
			    // 是否循环滚动(默认不是循环滚动)
			    isCycle = (isScroll.cycle || $(isScroll.body).attr('id').split('-')[2]==='cycle') || false;
			
			    // 纵向滚动
			    if (direction.toUpperCase() === 'H') {
				    /** 
				    * 循环滚动实现原理:
				    * ============================================
				    * 1. 同时滚动上一个和当前项;上一个向上滚动到可视
				    *    区域的上方,以本组建的效果为例,从top:0滚动
				    *    到-500px,刚好看不到上一个区域;当前项从
				    *    top:500px滚动到top:0,刚好全部显示
				    * 2. 滚动完毕后,当前项就是上一个区域了,如此循环
				    */
				    if (isCycle) {
						// 页面刚加载
						if (setting.isFirstView) {
							// 设置当前向的 z-index:4:默认CSS设置的滚动区域的z-index都为3
							// 浏览器默认会把最后一项展示到最上面,连续滚动都是从第一个开始
							// 设置为4后,则浏览器就把第一项显示到最上面了
							curContent.css({
								'z-index': 4
							});
						}
						else {
							// 已经开始滚动了
							// =====================================
							// 显示上一项和当前项:z-index:4
							// 上一项完全显示:top:0
							$(setting.lastContent).css({
								'z-index': 4,
								'top': 0
							}).animate({
								// 上一项滚动到看不到:top:-500px
								top: -isScroll.itemHeight
							});
							// 当前项刚好隐藏到显示区域下方:top:500px
							curContent.css({
								'z-index': 4,
								'top': isScroll.itemHeight + 'px'
							}).animate({
								// 滚动到完全显示:top:0
								'top': 0
							});
						}
						
						// 当前项就是上一项
						setting.lastContent = curContent;
					}
					else {
						// 普通滚动
						$(isScroll.body).animate({
							'top': -(tabIndex * isScroll.itemHeight)
						});
					}
			    }
			    else {
				    // 纵向滚动
				    if (isCycle) {
						if (setting.isFirstView) {
							curContent.css({
								'z-index': 4,
								'left': 0
							});
						}
						else {
							$(setting.lastContent).css({
								'z-index': 4,
								'left': 0
							}).animate({
								left: -isScroll.itemWidth
							});
							curContent.css({
								'z-index': 4,
								'left': isScroll.itemWidth + 'px'
							}).animate({
								'left': 0
							});
						}
						setting.lastContent = curContent;
					}
					else {
						$(isScroll.body).css('width', (tabs.length * isScroll.itemWidth) + 'px').animate({
							'left': -(tabIndex * isScroll.itemWidth)
						});
					}
			    }
		    }
		    else {
			    // ajaxTab导航
			    if (isAjax) {
					// 显示 Ajax 的数据
					this.ajaxInject(tabIndex);
				}
				else {
					// 设置了透明过度效果,页面刚加载时不用透明过度
					if (isFade && !setting.isFirstView) {
						timer = setTimeout(fadeIn, isFade.speed);
					}
					else {
						showCurContent();
					}
				}
		    }
		
		    setting.isFirstView = false;
		
		    // 设置当前选中项为上次选中项
		    setting.lastIndex = tabIndex;
		    setting.lastTab = curTab;
			
			if (!isAjax) {
				// 如果有回调函数
				if (callback && $.isFunction(callback)) {
					callback(tabIndex, tabs, contents, tabsView);
				}
			}
		
		    return this;
	    },
        /**
         * 获得 URL 中的 tab 当前选中项的 hash 字符
         *
         * @method getURIHash
         * @return {String} tabURIHash
         */
	    getURIHash: function(){
			var url = location.href, tabURIHash = '';
			
			// 直接根据('#')hash 值获得字符串
			// Hash 值优先级最高
			if (url.indexOf('#') > -1) {
				tabURIHash = url.split('#')[1];
			}
			else {
				// 根据 URL 中的参数(tab=1)获得 hash 字符串
				if (url.indexOf('tab=') > -1) {
					tabURIHash = url.split('tab=')[1];
					// 如果有多个参数,过滤出字符串
					if (tabURIHash.indexOf('&') >= 1) {
						tabURIHash = tabURIHash.split('&')[0];
					}
				}
			}
			
			return tabURIHash;
		},
        /**
         * 根据 URL 中的 hash 值获得默认选中项在 tabs 中的索引值
         *
         * @method getHashIndex
         * @return {Number} tabIndex - -1:没有值;>=0:有值
         */
	    getHashIndex: function(){
			var tabs = this.setting.tabs, tabURIHash = this.getURIHash(), tabIndex = -1;
			
			// 如果
			if (tabURIHash) {
				// 遍历 tabs 的 NodeList,根据 tab(li标签)的 id 属性值
				// 或者根据连接(li 中的 a 标签)的 rel 属性值获得索引值
				tabs.each(function(i, tab){
					var links = $(tab).find('a');
					
					// 获得 id 值,id 值优先级高于 a 连接的 rel 属性值获得索引值
					if ($(tab).attr('id') === tabURIHash) {
						tabIndex = i;
					}
					else {
						// 如果有链接,则根据第一个链接的值获得 rel 属性值获得索引值
						if (links.length > 0) {
							if ($(links[0]).attr('rel') === tabURIHash) {
								tabIndex = i;
							}
						}
					}
				});
			}
			
			return tabIndex;
		},
	    ajaxInject: function(tabIndex){
			var tabsView = this, 
			    setting = this.setting, 
				tabs = setting.tabs, 
				content = setting.lastContent, 
				curTab = $(tabs[tabIndex]), 
				filename = curTab.attr('id') || $(curTab.find('a')[0]).attr('rel'), 
				Ajax = setting.Ajax, 
				dataType = Ajax.dataType.toLowerCase(), 
				extName = dataType === 'json' ? 'js' : dataType, 
				path = Ajax.dataPath + '/' + filename + '.' + extName;
			
			// 未请求过改 tab 的内容
			if (!Ajax.cacheData[tabIndex]) {
				// 进行 Ajax 操作
				$.Ajax({
					url: path,
					method: 'GET',
					dataType: Ajax.dataType,
					cache: true,
					success: function(jqXHR){
						var data = jqXHR.html;
						
						// 显示数据	
						content.html(data);
						
						// 缓存数据
						Ajax.cacheData[tabIndex] = data;
						
						if(callback && $.isFunction(callback)){
							callback(tabIndex, tabs, contents, tabsView);
						}
					},
					error: function(jqXHR, textStatus, errorThrown){
						alert(errorThrown);
					}
				});
			}
			else {
				// 已经请求过的,直接显示缓存数据,不再执行 Ajax 请求
				content.html(Ajax.cacheData[tabIndex]);
			}
		},
        /**
         * 自动切换
         *
         * @method autoChange
         * @return {Object} jQuery.tabsView
         */
	    autoChange: function(){
			var tabsView = this, 
			    setting = this.setting, 
				speed = setting.auto.speed || 4000, 
				tabs = setting.tabs, 
				len = tabs.length;
			
			// 当前索引值递增切换
			setting.lastIndex += 1;
			
			// 释放定时器的资源
			if (setting.timer) {
				clearTimeout(setting.timer);
				setting.timer = null;
			}
			
			// 切换到最后一项,则转到第一项
			if (setting.lastIndex >= len) {
				setting.lastIndex = 0;
			}
			
			// 设置当前选中项
			this.setCurrent(setting.lastIndex);
			
			// 定时器,默认 4 秒切换一次
			setting.timer = setTimeout(function(){
				tabsView.autoChange.call(tabsView);
			}, speed);
			
			return this;
		},
        /**
         * 获得默认显示项 tabs 的索引值
         *
         * @method getDefaultIndex
         * @return {Number} jQuery.tabsView.setting.defaultIndex
         */
	    getDefaultIndex: function(){
			return this.setting.defaultIndex;
		},
	    getDefaultData: function(){
			return this.setting.defaultData;
		},
        /**
         * 获得上次显示项 tabs 的索引值
         *
         * @method getLastIndex
         * @return {Number} jQuery.tabsView.setting.getLastIndex
         */
	    getLastIndex: function(){
			return this.setting.lastIndex;
		},
	    getAjaxCache: function(){
			return this.setting.Ajax.cacheData || [];
		}
    };
	
	$.fn.extend({
		tabs: function(options){
		   options.root = $(this);
		   
		   return new $.tabsView(options);
		}
	});
})(jQuery);

声明:本文采用BY-NC-SA协议进行授权。转载请注明转自:tabsView – 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)