1// Tabbing jQuery plugin v2.0 2// https://github.com/dansdom/plugins-tab-nav 3// v 1.0 - basic functionality 4// v 2.0 - moved to new plugin architecture 5 6(function ($) { 7 // this ones for you 'uncle' Doug! 8 'use strict'; 9 10 // Plugin namespace definition 11 $.Tabs = function (options, element, callback) 12 { 13 // wrap the element in the jQuery object 14 this.el = $(element); 15 // this is the namespace for all bound event handlers in the plugin 16 this.namespace = "Tabs"; 17 // extend the settings object with the options, make a 'deep' copy of the object using an empty 'holding' object 18 this.opts = $.extend(true, {}, $.Tabs.settings, options); 19 this.init(); 20 // run the callback function if it is defined 21 if (typeof callback === "function") 22 { 23 callback.call(); 24 } 25 }; 26 27 // these are the plugin default settings that will be over-written by user settings 28 $.Tabs.settings = { 29 'tabNav': '.tabNav ul', 30 'tabContent': '.tabContent', 31 'startTab' : 1, 32 'activeClass' : 'active', 33 'fadeIn' : false, 34 'fadeSpeed' : 300, 35 'inputEvent' : 'click', 36 'onOpen' : function() {} 37 }; 38 39 // plugin functions go here 40 $.Tabs.prototype = { 41 init : function() { 42 // going to need to define this, as there are some anonymous closures in this function. 43 // something interesting to consider 44 var tabs = this; 45 46 // this seems a bit hacky, but for now I will unbind the namespace first before binding 47 this.destroy(); 48 49 this.el.nav = $(this.opts.tabNav); 50 this.el.content = $(this.opts.tabContent); 51 this.el.tabLength = this.el.content.children().length; 52 this.el.index = this.opts.startTab; 53 54 // show the first tab 55 this.getFirstTab(); 56 57 // do the main navigation here 58 this.el.nav.children().bind(this.opts.inputEvent + '.' + this.namespace, function() { 59 // get the index 60 tabs.el.index = $(this).parent().children().index(this); 61 // remove active class then add it to current item 62 tabs.el.nav.children().removeClass(tabs.opts.activeClass); 63 $(this).addClass(tabs.opts.activeClass); 64 // hide tab 65 tabs.el.content.children().css("display","none"); 66 // if fade effect then fade it, else just display block 67 if (tabs.opts.fadeIn) 68 { 69 tabs.el.content.children(":eq(" + tabs.el.index + ")").fadeIn(tabs.opts.fadeSpeed); 70 71 } 72 else 73 { 74 tabs.el.content.children(":eq(" + tabs.el.index + ")").css("display","block"); 75 } 76 // if there is an on open function then call it 77 tabs.opts.onOpen(); 78 return false; 79 }); 80 81 }, 82 getFirstTab : function() 83 { 84 // show the startTab. 85 if (this.opts.startTab > this.el.tabLength) 86 { 87 // show the first tab 88 this.el.index = 1; 89 } 90 // convert it into an array index 91 this.el.index--; // so the first tab is equal to 0 92 // check that it isn't below 0 93 if (this.el.index < 0) 94 { 95 this.el.index = 0; 96 } 97 98 // show the active tab 99 this.el.content.children(":eq(" + this.el.index + ")").css("display","block"); 100 this.el.nav.children().removeClass(this.opts.activeClass); 101 this.el.nav.children(":eq(" + this.el.index + ")").addClass(this.opts.activeClass); 102 }, 103 option : function(args) { 104 this.opts = $.extend(true, {}, this.opts, args); 105 }, 106 destroy : function() { 107 this.el.unbind("." + this.namespace); 108 } 109 }; 110 111 // the plugin bridging layer to allow users to call methods and add data after the plguin has been initialised 112 // props to https://github.com/jsor/jcarousel/blob/master/src/jquery.jcarou
112sel.js for the base of the code & http://isotope.metafizzy.co/ for a good implementation 113 $.fn.tabs = function(options, callback) { 114 // define the plugin name here so I don't have to change it anywhere else. This name refers to the jQuery data object that will store the plugin data 115 var pluginName = "tabs", 116 args; 117 118 // if the argument is a string representing a plugin method then test which one it is 119 if ( typeof options === 'string' ) { 120 // define the arguments that the plugin function call may make 121 args = Array.prototype.slice.call( arguments, 1 ); 122 // iterate over each object that the function is being called upon 123 this.each(function() { 124 // test the data object that the DOM element that the plugin has for the DOM element 125 var pluginInstance = $.data(this, pluginName); 126 127 // if there is no data for this instance of the plugin, then the plugin needs to be initialised first, so just call an error 128 if (!pluginInstance) { 129 alert("The plugin has not been initialised yet when you tried to call this method: " + options); 130 return; 131 } 132 // if there is no method defined for the option being called, or it's a private function (but I may not use this) then return an error. 133 if (!$.isFunction(pluginInstance[options]) || options.charAt(0) === "_") { 134 alert("the plugin contains no such method: " + options); 135 return; 136 } 137 // apply the method that has been called 138 else { 139 pluginInstance[options].apply(pluginInstance, args); 140 } 141 }); 142 143 } 144 // initialise the function using the arguments as the plugin options 145 else { 146 // initialise each instance of the plugin 147 this.each(function() { 148 // define the data object that is going to be attached to the DOM element that the plugin is being called on 149 var pluginInstance = $.data(this, pluginName); 150 // if the plugin instance already exists then apply the options to it. I don't think I need to init again, but may have to on some plugins 151 if (pluginInstance) { 152 pluginInstance.option(options); 153 // initialising the plugin here may be dangerous and stack multiple event handlers. if required then the plugin instance may have to be 'destroyed' first 154 //pluginInstance.init(callback); 155 } 156 // initialise a new instance of the plugin 157 else { 158 $.data(this, pluginName, new $.Tabs(options, this, callback)); 159 } 160 }); 161 } 162 163 // return the jQuery object from here so that the plugin functions don't have to 164 return this; 165 }; 166 167 // end of module 168})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.