Files
2026-02-03 15:31:29 +05:00

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();
});