UNPKG

materialize-css

Version:

Builds Materialize distribution packages

234 lines (199 loc) 7.66 kB
(function ($) { var methods = { init : function(options) { var defaults = { onShow: null, swipeable: false, responsiveThreshold: Infinity, // breakpoint for swipeable }; options = $.extend(defaults, options); return this.each(function() { // For each set of tabs, we want to keep track of // which tab is active and its associated content var $this = $(this), window_width = $(window).width(); var $active, $content, $links = $this.find('li.tab a'), $tabs_width = $this.width(), $tabs_content = $(), $tabs_wrapper, $tab_width = Math.max($tabs_width, $this[0].scrollWidth) / $links.length, $indicator, index = prev_index = 0, clicked = false, clickedTimeout, transition = 300; // Finds right attribute for indicator based on active tab. // el: jQuery Object var calcRightPos = function(el) { return $tabs_width - el.position().left - el.outerWidth() - $this.scrollLeft(); }; // Finds left attribute for indicator based on active tab. // el: jQuery Object var calcLeftPos = function(el) { return el.position().left + $this.scrollLeft(); }; // Animates Indicator to active tab. // prev_index: Number var animateIndicator = function(prev_index) { if ((index - prev_index) >= 0) { $indicator.velocity({"right": calcRightPos($active) }, { duration: transition, queue: false, easing: 'easeOutQuad'}); $indicator.velocity({"left": calcLeftPos($active) }, {duration: transition, queue: false, easing: 'easeOutQuad', delay: 90}); } else { $indicator.velocity({"left": calcLeftPos($active) }, { duration: transition, queue: false, easing: 'easeOutQuad'}); $indicator.velocity({"right": calcRightPos($active) }, {duration: transition, queue: false, easing: 'easeOutQuad', delay: 90}); } }; // Change swipeable according to responsive threshold if (options.swipeable) { if (window_width > options.responsiveThreshold) { options.swipeable = false; } } // If the location.hash matches one of the links, use that as the active tab. $active = $($links.filter('[href="'+location.hash+'"]')); // If no match is found, use the first link or any with class 'active' as the initial active tab. if ($active.length === 0) { $active = $(this).find('li.tab a.active').first(); } if ($active.length === 0) { $active = $(this).find('li.tab a').first(); } $active.addClass('active'); index = $links.index($active); if (index < 0) { index = 0; } if ($active[0] !== undefined) { $content = $($active[0].hash); $content.addClass('active'); } // append indicator then set indicator width to tab width if (!$this.find('.indicator').length) { $this.append('<div class="indicator"></div>'); } $indicator = $this.find('.indicator'); // we make sure that the indicator is at the end of the tabs $this.append($indicator); if ($this.is(":visible")) { // $indicator.css({"right": $tabs_width - ((index + 1) * $tab_width)}); // $indicator.css({"left": index * $tab_width}); setTimeout(function() { $indicator.css({"right": calcRightPos($active) }); $indicator.css({"left": calcLeftPos($active) }); }, 0); } $(window).resize(function () { $tabs_width = $this.width(); $tab_width = Math.max($tabs_width, $this[0].scrollWidth) / $links.length; if (index < 0) { index = 0; } if ($tab_width !== 0 && $tabs_width !== 0) { $indicator.css({"right": calcRightPos($active) }); $indicator.css({"left": calcLeftPos($active) }); } }); // Initialize Tabs Content. if (options.swipeable) { // TODO: Duplicate calls with swipeable? handle multiple div wrapping. $links.each(function () { var $curr_content = $(Materialize.escapeHash(this.hash)); $curr_content.addClass('carousel-item'); $tabs_content = $tabs_content.add($curr_content); }); $tabs_wrapper = $tabs_content.wrapAll('<div class="tabs-content carousel"></div>'); $tabs_content.css('display', ''); $('.tabs-content.carousel').carousel({ fullWidth: true, noWrap: true, onCycleTo: function(item) { if (!clicked) { var prev_index = index; index = $tabs_wrapper.index(item); $active = $links.eq(index); animateIndicator(prev_index); } }, }); } else { // Hide the remaining content $links.not($active).each(function () { $(Materialize.escapeHash(this.hash)).hide(); }); } // Bind the click event handler $this.on('click', 'a', function(e) { if ($(this).parent().hasClass('disabled')) { e.preventDefault(); return; } // Act as regular link if target attribute is specified. if (!!$(this).attr("target")) { return; } clicked = true; $tabs_width = $this.width(); $tab_width = Math.max($tabs_width, $this[0].scrollWidth) / $links.length; // Make the old tab inactive. $active.removeClass('active'); var $oldContent = $content // Update the variables with the new link and content $active = $(this); $content = $(Materialize.escapeHash(this.hash)); $links = $this.find('li.tab a'); var activeRect = $active.position(); // Make the tab active. $active.addClass('active'); prev_index = index; index = $links.index($(this)); if (index < 0) { index = 0; } // Change url to current tab // window.location.hash = $active.attr('href'); // Swap content if (options.swipeable) { if ($tabs_content.length) { $tabs_content.carousel('set', index); } } else { if ($content !== undefined) { $content.show(); $content.addClass('active'); if (typeof(options.onShow) === "function") { options.onShow.call(this, $content); } } if ($oldContent !== undefined && !$oldContent.is($content)) { $oldContent.hide(); $oldContent.removeClass('active'); } } // Reset clicked state clickedTimeout = setTimeout(function(){ clicked = false; }, transition); // Update indicator animateIndicator(prev_index); // Prevent the anchor's default click action e.preventDefault(); }); }); }, select_tab : function( id ) { this.find('a[href="#' + id + '"]').trigger('click'); } }; $.fn.tabs = function(methodOrOptions) { if ( methods[methodOrOptions] ) { return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { // Default to "init" return methods.init.apply( this, arguments ); } else { $.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.tabs' ); } }; $(document).ready(function(){ $('ul.tabs').tabs(); }); }( jQuery ));