361 lines
15 KiB
JavaScript
361 lines
15 KiB
JavaScript
theme.Tabs = function() {
|
|
|
|
function Tabs() {
|
|
|
|
this.selectors = {
|
|
elements: '[data-js-tabs]'
|
|
};
|
|
|
|
this.load();
|
|
};
|
|
|
|
Tabs.prototype = $.extend({}, Tabs.prototype, {
|
|
init: function ($tabs) {
|
|
var $tabs = $tabs || $('.js-tabs').not('.tabs--init');
|
|
|
|
var tabsObj = {
|
|
singleOpen: true,
|
|
anim_tab_duration: function () {
|
|
return theme.animations.tabs.duration * 1000;
|
|
},
|
|
anim_scroll_duration: function () {
|
|
return theme.animations.tabs.scroll_duration * 1000;
|
|
},
|
|
toggleOnDesktop: true,
|
|
scrollToOpenMobile: true,
|
|
effect: 'slide',
|
|
offsetTop: '.header__content.header__content--sticky'
|
|
};
|
|
|
|
if($tabs.hasClass('product-tabs')) {
|
|
tabsObj = $.extend(tabsObj, {
|
|
goToTab: [
|
|
{
|
|
elem: '.spr-badge-caption',
|
|
tab: 'reviews'
|
|
}
|
|
]
|
|
});
|
|
}
|
|
|
|
$tabs.ttTabs(tabsObj);
|
|
},
|
|
load: function() {
|
|
$.fn.ttTabs = function (options) {
|
|
function ttTabs(tabs) {
|
|
var $tabs = $(tabs),
|
|
$head = $tabs.find('[data-js-tabs-head]'),
|
|
$slider = $tabs.find('[data-js-tabs-slider]'),
|
|
$head_btns = $tabs.find('[data-js-tabs-btn]'),
|
|
$body_btns = $tabs.find('[data-js-tabs-btn-mobile]'),
|
|
$body_tabs = $tabs.find('[data-js-tabs-tab]'),
|
|
$btn_prev = $tabs.find('[data-js-tabs-nav-prev]'),
|
|
$btn_next = $tabs.find('[data-js-tabs-nav-next]'),
|
|
breakpoint = 1024,
|
|
type = $tabs.attr('data-type'),
|
|
scrollToOpenMobile = (options.scrollToOpenMobile !== undefined) ? options.scrollToOpenMobile : true,
|
|
singleOpen = (options.singleOpen !== undefined) ? options.singleOpen : true,
|
|
toggleOnDesktop = (options.toggleOnDesktop !== undefined) ? options.toggleOnDesktop : true,
|
|
effect = (options.effect !== undefined) ? options.effect : 'slide',
|
|
goToTab = options.goToTab;
|
|
|
|
function _closeTab($btn, data) {
|
|
var $animElem,
|
|
this_effect = data.effect || effect,
|
|
anim_obj = {
|
|
duration: options.anim_tab_duration(),
|
|
complete: function () {
|
|
$(this).removeAttr('style');
|
|
}
|
|
};
|
|
|
|
function _anim_func($animElem) {
|
|
switch(this_effect) {
|
|
case 'toggle':
|
|
$animElem.hide().removeAttr('style');
|
|
break;
|
|
case 'slide':
|
|
$animElem.velocity('slideUp', anim_obj);
|
|
break;
|
|
default:
|
|
$animElem.velocity('slideUp', anim_obj);
|
|
}
|
|
};
|
|
|
|
if(data.desktop || singleOpen) {
|
|
$head_btns.removeClass('active');
|
|
$animElem = $body_tabs.filter('.active').removeClass('active').find('[data-js-tabs-content]').stop();
|
|
|
|
_anim_func($animElem);
|
|
} else {
|
|
var index = $head_btns.index($btn);
|
|
|
|
$btn.removeClass('active');
|
|
$animElem = $body_tabs.eq(index).removeClass('active').find('[data-js-tabs-content]').stop();
|
|
|
|
_anim_func($animElem);
|
|
}
|
|
};
|
|
|
|
function _openTab($btn, data) {
|
|
var index = $head_btns.index($btn),
|
|
$body_tab_act = $body_tabs.eq(index),
|
|
$animElem,
|
|
$sticky = $('.js-sticky-sidebar'),
|
|
this_effect = data.effect || effect,
|
|
anim_obj = {
|
|
duration: options.anim_tab_duration(),
|
|
progress: function () {
|
|
if(theme.StickySidebar) {
|
|
theme.StickySidebar.update($sticky);
|
|
}
|
|
},
|
|
complete: function () {
|
|
if(data.after) {
|
|
data.after($body_tab_act);
|
|
}
|
|
|
|
if(theme.StickySidebar) {
|
|
theme.StickySidebar.update($sticky);
|
|
}
|
|
}
|
|
};
|
|
|
|
function _anim_func($animElem) {
|
|
if($slider.hasClass('slick-initialized')) {
|
|
var btn_l = $btn.last().get(0).getBoundingClientRect().left,
|
|
btn_r = $btn.last().get(0).getBoundingClientRect().right,
|
|
slider_l = $slider.get(0).getBoundingClientRect().left,
|
|
slider_r = $slider.get(0).getBoundingClientRect().right;
|
|
|
|
if(btn_r > slider_r) $slider.slick('slickNext');
|
|
else if(btn_l < slider_l) $slider.slick('slickPrev');
|
|
}
|
|
|
|
switch(this_effect) {
|
|
case 'toggle':
|
|
$animElem.show();
|
|
if(data.after) {
|
|
data.after($body_tab_act);
|
|
}
|
|
break;
|
|
case 'slide':
|
|
$animElem.velocity('slideDown', anim_obj);
|
|
break;
|
|
default:
|
|
$animElem.velocity('slideDown', anim_obj);
|
|
}
|
|
};
|
|
|
|
$btn.addClass('active');
|
|
$animElem = $body_tab_act.addClass('active').find('> div').stop();
|
|
|
|
_anim_func($animElem);
|
|
};
|
|
|
|
function _toTab(tab) {
|
|
var wind_w = window.innerWidth,
|
|
desktop = wind_w > breakpoint,
|
|
$btn = $head_btns.filter('[data-tab="' + tab + '"]');
|
|
|
|
function afterOpen() {
|
|
var tob_t = type === 'horizontal' && desktop ? $tabs.offset().top : $body_btns.eq($head_btns.index($btn)).offset().top,
|
|
header_h = theme.StickyHeader && theme.StickyHeader.$sticky ? theme.StickyHeader.$sticky.stickyHeader('getStickyHeight') : 0;
|
|
|
|
$('html, body').velocity( 'scroll' , {
|
|
offset: tob_t - header_h,
|
|
duration: options.anim_scroll_duration()
|
|
});
|
|
};
|
|
|
|
if(!$btn.hasClass('active')) {
|
|
_closeTab($btn, {
|
|
desktop: desktop,
|
|
effect: 'toggle'
|
|
});
|
|
|
|
_openTab($btn, {
|
|
desktop: desktop,
|
|
effect: 'toggle',
|
|
after: function () {
|
|
afterOpen();
|
|
}
|
|
});
|
|
} else {
|
|
afterOpen();
|
|
}
|
|
};
|
|
|
|
function _btn_disabled(currentSlide) {
|
|
var btn_last_r = $head_btns.last().get(0).getBoundingClientRect().right,
|
|
slider_r = $slider.get(0).getBoundingClientRect().right;
|
|
|
|
if(currentSlide === 0) $btn_prev.addClass('disabled');
|
|
else $btn_prev.removeClass('disabled');
|
|
|
|
if(btn_last_r <= slider_r) $btn_next.addClass('disabled');
|
|
else $btn_next.removeClass('disabled');
|
|
};
|
|
|
|
function _slider_init() {
|
|
if($slider.hasClass('slick-initialized')) return;
|
|
|
|
$head.addClass('tabs__head--slider');
|
|
|
|
$slider.slick({
|
|
infinite: false,
|
|
slidesToShow: 1,
|
|
variableWidth: true,
|
|
draggable: false,
|
|
dots: false,
|
|
arrows: false
|
|
});
|
|
|
|
$btn_prev.addClass('disabled');
|
|
|
|
$slider.on('afterChange', function(e, slick, currentSlide) {
|
|
_btn_disabled(currentSlide);
|
|
});
|
|
|
|
$btn_prev.on('click', function() {
|
|
if($(this).hasClass('disabled')) return;
|
|
$slider.slick('slickPrev');
|
|
});
|
|
|
|
$btn_next.on('click', function() {
|
|
if($(this).hasClass('disabled')) return;
|
|
$slider.slick('slickNext');
|
|
});
|
|
};
|
|
|
|
function _slider_destroy() {
|
|
if(!$slider.hasClass('slick-initialized')) return;
|
|
|
|
$($slider, $btn_prev, $btn_next).off();
|
|
|
|
$slider.slick('unslick');
|
|
|
|
$head.removeClass('tabs__head--slider');
|
|
};
|
|
|
|
$head_btns.on('click', function (e, trigger) {
|
|
var $this = $(this),
|
|
wind_w = window.innerWidth,
|
|
desktop = wind_w > breakpoint,
|
|
trigger = (trigger === 'trigger') ? true : false;
|
|
|
|
if($this.hasClass('active')) {
|
|
if(desktop && !toggleOnDesktop) return;
|
|
|
|
_closeTab($this, {
|
|
desktop: desktop
|
|
});
|
|
} else {
|
|
_closeTab($this, {
|
|
desktop: desktop
|
|
});
|
|
|
|
_openTab($this, {
|
|
desktop: desktop,
|
|
after: function ($body_tab_act) {
|
|
if (!desktop && !trigger && scrollToOpenMobile) {
|
|
var tob_t = $body_tab_act.find('[data-js-tabs-btn-mobile]').offset().top,
|
|
header_h = theme.StickyHeader && theme.StickyHeader.$sticky ? theme.StickyHeader.$sticky.stickyHeader('getStickyHeight') : 0;
|
|
|
|
$('html, body').velocity('stop').velocity('scroll', {
|
|
offset: tob_t - header_h,
|
|
duration: options.anim_scroll_duration()
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
$body_btns.on('click', function () {
|
|
var $this = $(this),
|
|
$parent = $this.parent(),
|
|
index = $body_tabs.index($parent);
|
|
|
|
$head_btns.eq(index).trigger('click');
|
|
});
|
|
|
|
if($.isArray(goToTab) && goToTab.length) {
|
|
$(goToTab).each(function () {
|
|
var _ = this;
|
|
|
|
$body.on('click', this.elem, function (e) {
|
|
_toTab(_.tab, _.scrollTo, _.focus);
|
|
|
|
e.preventDefault();
|
|
return false;
|
|
});
|
|
});
|
|
}
|
|
|
|
if(type === 'horizontal') {
|
|
$(window).on('theme.resize updateTabs', function () {
|
|
var wind_w = window.innerWidth,
|
|
desktop = wind_w > breakpoint,
|
|
head_w = $slider.innerWidth(),
|
|
btns_w = 0;
|
|
|
|
$head_btns.each(function () {
|
|
btns_w += $(this).innerWidth();
|
|
});
|
|
|
|
if(desktop) {
|
|
var $btn_act = $head_btns.filter('.active');
|
|
|
|
if(!singleOpen && $btn_act.length > 1) {
|
|
var $save_active = $btn_act.first();
|
|
|
|
_closeTab('', {
|
|
desktop: desktop
|
|
});
|
|
|
|
_openTab($save_active, {
|
|
desktop: desktop
|
|
});
|
|
}
|
|
|
|
if(btns_w > head_w) {
|
|
_slider_init();
|
|
if($slider.hasClass('slick-initialized')) {
|
|
setTimeout(function() {
|
|
_btn_disabled($head_btns.index($('[data-js-tabs-btn].slick-current')));
|
|
}, 0);
|
|
}
|
|
} else {
|
|
_slider_destroy();
|
|
}
|
|
} else {
|
|
_slider_destroy();
|
|
}
|
|
});
|
|
}
|
|
|
|
$head_btns.filter('[data-active="true"]').trigger('click', ['trigger']);
|
|
|
|
$(window).trigger('updateTabs');
|
|
|
|
$tabs.addClass('tabs--init');
|
|
|
|
return $tabs;
|
|
};
|
|
|
|
$(this).each(function() {
|
|
new ttTabs(this);
|
|
});
|
|
};
|
|
|
|
this.init();
|
|
}
|
|
});
|
|
|
|
theme.Tabs = new Tabs;
|
|
};
|
|
|
|
$(function() {
|
|
theme.Tabs();
|
|
}); |