请选择 进入手机版 | 继续访问电脑版

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 新增登录提醒插件 - 用至我的站点 地图任务一定要做 - 给官方提建议

论坛活动及任务 地图和邮件任务 请多用悬赏提问 热夏来袭,选一款蓝色理想的个性T恤吧!

MIUI手机主题设计大赛,奔驰大奖等你拿! 想加薪?!蓝色理想招聘提供你更多机会 悬赏答疑,赚取积分兑奖品!

查看: 339|回复: 2

学用jQuery,写了一个简单的tabsView。 [复制链接]

yaohaixiao 楼主

会武术的科学家

实习版主

帖子
2057
体力
5638
威望
45
居住地
浙江省 杭州市
发表于 2012-1-5 21:46:22 |显示全部楼层
本帖最后由 yaohaixiao 于 2012-1-5 21:52 编辑

jQuery 用得还不是太熟悉,自己开始写些简单的控件,呵呵,还是从最常用的tabsView开始吧,看看:

1. 支持tab键切换。
2. 支持ajax切换。
3. 可以设置默认显示项
4. 一开始可以显示全部内容
5. 可以根据路径的hash值,设置默认显示项
6. 可以设置切换的触发事件
7. 切换完成后,可以执行回调方法

基本常用的方法都有了,如果你还在找tabsView,或者想学学实现原理,可以看看,当然如果有BUG,也不奇怪,希望大家指正。
  1. /**
  2. * @author Yaohaixiao
  3. */
  4. jQuery.tabsView = function(config){       
  5.         // 初始化配置项       
  6.         this.setting = {
  7.                 tabs: null,
  8.                 contents: null,
  9.                 lastTab: null,
  10.                 lastContent: null,
  11.                 lastIndex: 0,
  12.                 defaultIndex: 0,
  13.                 hashFirst: false,
  14.                 showAll: false,
  15.                 ajax: null,
  16.                 evtType: 'click',
  17.                 focusEvt: true,
  18.                 callback: null
  19.         };
  20.        
  21.         // 合并配置信息
  22.         $.extend(this.setting, config);
  23.        
  24.         // 初始化
  25.         this.initializer();
  26.        
  27.         return this;
  28. };

  29. jQuery.tabsView.prototype = {
  30.         /**
  31.          * 初始化 tabView
  32.          *
  33.          * @method initializer
  34.          * @return {Object} jQuery.tabsView
  35.          */
  36.         initializer: function(){
  37.                 // 获得默认的 lastTab 和 lastContent
  38.                 this.getDefTab();
  39.                 this.getDefContent();
  40.                
  41.                 // 设置默认的选中内容
  42.                 this.setDefSelection();
  43.                
  44.                 // 绑定 tabView 组件的 UI 处理函数
  45.                 this.bindUI();
  46.                
  47.                 return this;
  48.         },
  49.         setDefSelection: function(){
  50.                 var tabsView = this,
  51.                     setting = this.setting,
  52.                         tabs = setting.tabs,
  53.                         contents = setting.contents,
  54.                         tabHash = this._getTabHash(),
  55.                         showAll = setting.showAll;
  56.                
  57.                 if (!showAll) {
  58.                         // 如果有 url 的 hash值,默认显示项的设置以 hash 值为优先设置
  59.                         if (tabHash && setting.hashFirst) {
  60.                                 $(tabs).each(function(i, tab){
  61.                                         var curTitle = $(tab).attr('title');
  62.                                        
  63.                                         if (curTitle === tabHash) {
  64.                                                 tabsView.setCurrent(i);
  65.                                         }
  66.                                 });
  67.                         }
  68.                         else {
  69.                                 // 没有 URL 的 hash 值,则显示配置项中设置的默认项
  70.                                 this.setCurrent(setting.defaultIndex);
  71.                         }
  72.                 }
  73.                 else{
  74.                         // 显示所有的 contents
  75.                         $(contents).removeClass('hide');
  76.                 }
  77.                
  78.                 return this;
  79.         },
  80.         /**
  81.          * 给 tabs 绑定事件
  82.          *
  83.          * @method fire
  84.          * @return {Object} jQuery.tabsView
  85.          */
  86.         bindUI: function(){
  87.                 var tabsView = this,
  88.                     setting = this.setting,
  89.                         tabs = setting.tabs;
  90.                
  91.                 // 给每个 tab 绑定处理方法
  92.                 $(tabs).each(function(i, tab){
  93.                         var curTab = $(tab);
  94.                        
  95.                         curTab[setting.evtType](function(evt){
  96.                                 // 当前 tab 不触发事件
  97.                                 if (!curTab.hasClass('current')) {
  98.                                         tabsView.setCurrent(i);
  99.                                 }
  100.                                 // 阻止冒泡和默认行为事件
  101.                                 evt.preventDefault();
  102.                                 evt.stopPropagation();
  103.                         });
  104.                        
  105.                         // Tab 键切换事件,使用 focusein 事件就可以了
  106.                         if (setting.focusEvt) {
  107.                                 curTab.focusin(function(evt){
  108.                                         // 当前 tab 不触发事件
  109.                                         if (!curTab.hasClass('current')) {
  110.                                                 tabsView.setCurrent(i);
  111.                                         }
  112.                                 });
  113.                         }
  114.                 });
  115.                
  116.                 return this;
  117.         },
  118.         _afterTabSelectedChange: function(){
  119.                 var callback = this.setting.callback;
  120.                
  121.                 // 如果设置了 tab 切换完成后的自定义方法,则执行它
  122.                 if (callback && $.isFunction(callback)) {
  123.                         callback();
  124.                 }
  125.                
  126.                 return this;
  127.         },
  128.         /**
  129.          * 设置当前选中项的样式和内容
  130.          *
  131.          * @method setCurrent
  132.          * @param {Number} curTabIndex
  133.          * @return {Object} jQuery.tabsView
  134.          */
  135.         setCurrent: function(curTabIndex){
  136.                 var setting = this.setting,
  137.                     tabs = setting.tabs,
  138.                     contents = setting.contents,
  139.                         curTab = tabs[curTabIndex],
  140.                         curCnt = contents[curTabIndex],
  141.                         fileName = '';
  142.                
  143.                 // 移除上次选中的 tab 的选中样式
  144.                 if (setting.lastTab) {
  145.                         $(setting.lastTab).removeClass('current');
  146.                 }
  147.                 // 隐藏上次 tab 项相关的内容
  148.                 if (setting.lastContent) {
  149.                         $(setting.lastContent).addClass('hide');
  150.                 }
  151.                
  152.                 // 将当前选中的 tab 显示为选中样式
  153.                 $(curTab).addClass('current');
  154.                 // 当前标签显示为选中样式后,当前标签就是上次选中标签了
  155.                 setting.lastTab = curTab;
  156.                 // 当前标签显示为选中样式后,当前标签的索引值就是上次选中标签索引值了
  157.                 setting.lastIndex = curTabIndex;
  158.                
  159.                 // 如果是 ajaxTab
  160.                 if (setting.ajax) {
  161.                         fileName = $(curTab).attr('title');
  162.                         this.ajaxInsert(fileName);
  163.                 }
  164.                 else {
  165.                         // 如果不是 ajaxTab                               
  166.                         $(curCnt).removeClass('hide'); // 显示当前选中项的相关内容
  167.                         setting.lastContent = curCnt; // 当前选中项的相关内容在现实后就是上次的选中项显示内容了
  168.                        
  169.                         this._afterTabSelectedChange();
  170.                 }
  171.                
  172.                 return this;
  173.         },
  174.         /**
  175.          * 显示 ajax 请求返回来的数据
  176.          *
  177.          * @method ajaxInsert
  178.          * @param {String} fileName
  179.          * @return {Object} jQuery.tabsView
  180.          */
  181.         ajaxInsert: function(fileName){
  182.                 var tabView = this,
  183.                     setting = this.setting,
  184.                     ajaxSet = setting.ajax,
  185.                     curAjaxType = 'GET',
  186.                         curAjaxTarget = null,
  187.                         curAjaxPath = '',
  188.                         curExtName = '.js',
  189.                         curAjaxDataType = 'JSON';
  190.                
  191.                 if (!ajaxSet.target || !ajaxSet.path) {
  192.                         return this;
  193.                 }
  194.                
  195.                 // 获得请求类型
  196.                 if (ajaxSet.type) {
  197.                         curAjaxType = ajaxSet.type.toUpperCase();
  198.                 }
  199.                 // 获得请求数据类型
  200.                 if (ajaxSet.dataType) {
  201.                         curAjaxDataType = ajaxSet.dataType.toUpperCase();
  202.                 }
  203.                 // 根据请求数据类型,获得文件扩展名,并组合成完整的请求路径
  204.                 switch (curAjaxDataType) {
  205.                         case 'JSON':
  206.                                 curExtName = '.js';
  207.                                 break;
  208.                         case 'HTML':
  209.                                 curExtName = '.htm';
  210.                                 break;
  211.                 }
  212.                 // 获得Ajax请求数据要插入的DOM对象
  213.                 curAjaxTarget = $(ajaxSet.target);
  214.                 // ajaxTab 请求的信息,只做展示之用,应该要缓存住,因此没有用  Math.random() 方法清除缓存
  215.                 curAjaxPath = ajaxSet.path + fileName + curExtName;
  216.                
  217.                 // 执行 ajax 请求
  218.                 $.ajax({
  219.                         type: curAjaxType,
  220.                         url: curAjaxPath,
  221.                         success: function(data){
  222.                                 var htmlContent = '';
  223.                                
  224.                                 switch (curAjaxDataType) {
  225.                                         case 'JSON':
  226.                                             htmlContent = data.html;
  227.                                                 break;
  228.                                         case 'HTML':
  229.                                             htmlContent = data;
  230.                                                 break;
  231.                                 }
  232.                                
  233.                                 curAjaxTarget.html(htmlContent);
  234.                                
  235.                                 tabView._afterTabSelectedChange();
  236.                         },
  237.                         dataType: curAjaxDataType
  238.                 });
  239.                
  240.                 return this;
  241.         },
  242.         _getDefSelection: function(){
  243.                 var defaultSelection = [],
  244.                     setting = this.setting,
  245.                         showAll = setting.showAll,
  246.                         ajax = setting.ajax,
  247.                         tabs = setting.tabs,
  248.                         contents = setting.contents;
  249.                
  250.                 // 显示默认的选中项和内容
  251.                 if (showAll) {
  252.                         // 默认的上次显示项为所有 tabs
  253.                         setting.lastTab = tabs;
  254.                         setting.lastContent = contents;
  255.                 }
  256.                 else {
  257.                         // 默认的上次显示项为第一个tab
  258.                         setting.lastTab = tabs[setting.lastIndex];
  259.                         // 如果是 ajaxTab 则上次显示的 content 为 null
  260.                         // 因为 ajaxTab 都是在一个 targetContent 中显示异步加载的信息
  261.                         if (!ajax) {
  262.                                 setting.lastContent = contents[setting.lastIndex];
  263.                         }
  264.                 }
  265.                
  266.                 defaultSelection = [setting.lastTab, setting.lastContent];
  267.                
  268.                 return defaultSelection;
  269.         },
  270.         _getTabHash: function(){
  271.                 var tabHash = '';
  272.                
  273.                 // 根据URL地址参数设置默认选中的 tab 显示项
  274.                 if (location.href.indexOf('tab=') > -1) {
  275.                         tabHash = location.href.split('tab=')[1];
  276.                        
  277.                         // URL地址如:tabs.htm?tab=javascript&id=4#xml
  278.                         if (tabHash.indexOf('&') > -1) {
  279.                                 tabHash = tabHash.split('&')[0];
  280.                         }
  281.                         else {
  282.                                 // URL地址如:tabs.htm?tab=javascript#xml
  283.                                 if (tabHash.indexOf('#') > -1) {
  284.                                         tabHash = tabHash.split('#')[0];
  285.                                 }
  286.                         }
  287.                 }
  288.                 else {
  289.                         // URL地址如:tabs.htm#xml
  290.                         if (location.href.indexOf('#') > -1) {
  291.                                 tabHash = location.href.split('#')[1];
  292.                         }
  293.                 }
  294.                
  295.                 return tabHash;
  296.         },
  297.         /**
  298.          * 获得 tabsView 实例的配置项信息
  299.          *
  300.          * @method getSetting
  301.          * @return {Object} this.setting
  302.          */
  303.         getSetting: function(){
  304.                 return this.setting;
  305.         },
  306.         /**
  307.          * 获得 tabsView 实例的 tabs 的 NodeList 信息
  308.          *
  309.          * @method getTabs
  310.          * @return {HTMLNodeList} this.setting.tabs
  311.          */
  312.         getTabs: function(){
  313.                 return this.setting.tabs;
  314.         },
  315.         /**
  316.          * 获得 tabsView 实例的 contents 的 NodeList 信息
  317.          *
  318.          * @method getContents
  319.          * @return {HTMLNodeList} this.setting.contents;
  320.          */
  321.         getContents: function(){
  322.                 return this.setting.contents;
  323.         },
  324.         getDefTab: function(){
  325.                 var defaultTab = this._getDefSelection()[0];
  326.                
  327.                 return defaultTab;
  328.         },
  329.         getDefContent: function(){
  330.                 var defaultContent = this._getDefSelection()[1];
  331.                
  332.                 return defaultContent;
  333.         },
  334.         getCurTab: function(){
  335.                 return this.setting.lastTab;
  336.         },
  337.         getCurContent: function(){
  338.                 return this.setting.lastContent;
  339.         },
  340.         /**
  341.          * 获得 tabsView 实例的 lastIndex 信息 - 当前选中标签在 tabs 中的索引值
  342.          *
  343.          * @method getContents
  344.          * @return {HTMLNodeList} this.setting.contents;
  345.          */
  346.         getCurIndex: function(){
  347.                 return this.setting.lastIndex;
  348.         }
  349. };

  350. /**
  351. * jQuery.tabsView 的静态方法,用来同时设置多个 tabsView
  352. *
  353. * @method tabs
  354. * @static
  355. * @return {Object|Array} tabs - 一个或者多个 jQuery.tabsView 的实例
  356. */
  357. jQuery.tabs = function(){
  358.         var tabs = [],
  359.             args = arguments,
  360.                 i = 0,
  361.                 len = args.length;
  362.        
  363.        
  364.         for (; i < len; i += 1) {
  365.                 tabs[i] = new jQuery.tabsView(args[i]);
  366.         }
  367.        
  368.         return len > 0 ? tabs : null;
  369. };
复制代码
附件: 你需要登录才可以下载或查看附件。没有帐号?注册
帖子
114
体力
448
威望
0
居住地
四川省 成都市
发表于 2012-1-5 22:03:10 |显示全部楼层
不错不错,收藏了!!
时尚女人http://www.xinfeishop.com

chenjmdgjl

高级会员

帖子
163
体力
886
威望
2
居住地
北京市 海淀区
发表于 2012-1-6 10:29:54 |显示全部楼层
注释写得挺好,顶一下。
CSS
您需要登录后才可以回帖 登录 | 注册


Archiver|手机版|blueidea.com ( 京ICP备05002321号 )    

GMT+8, 2012-6-2 08:37 , Processed in 0.132761 second(s), 7 queries , Gzip On, Memcache On.

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部