jQuery(function($) { // Mobile sidebars $.fn.expandableSidebar = function(expandedClass) { var $me = this; $me.on('click', function() { if(!$me.hasClass(expandedClass)) { $me.addClass(expandedClass); } else { $me.removeClass(expandedClass); } }); } // Interval loop $.fn.intervalLoop = function(condition, action, duration, limit) { var counter = 0; var looper = setInterval(function(){ if (counter >= limit || $.fn.checkIfElementExists(condition)) { clearInterval(looper); } else { action(); counter++; } }, duration); if (!condition) action(); } // Check if element exists $.fn.checkIfElementExists = function(selector) { return $(selector).length; } $.fn.hideDropdowns = function(dropdownClass) { this .removeClass(dropdownClass) .find('.wsite-menu-wrap') .revealer('hide') .find('.' + dropdownClass) .removeClass(dropdownClass); return this; } var edisonController = { init: function(opts) { var base = this; base._addClasses(); base._headerSetup(); $(window).on('resize', function() { base._headerSetup(); }); base._moveUtils(); base._navSetup(); base._searchBox(); base._miniCartSetup(); base._productSetup(); base._attachEvents(); }, _breakpoints: { small: 768, }, _utils: { onEscKey: function(callback) { $(document).on('keyup', function(event) { if (event.keyCode === 27) callback(); }); }, onScrollDirection: function(Direction) { var previousScrollTop = 0, deltaThreshold = 5; $(window).scroll(function() { var currentScrollTop = $(this).scrollTop(); //return if scroll hasn't met delta threshold if (Math.abs(previousScrollTop - currentScrollTop) <= deltaThreshold) { return; } //direction conditions if (currentScrollTop > previousScrollTop){ Direction.down(currentScrollTop); } else { Direction.up(currentScrollTop); } previousScrollTop = currentScrollTop; }); }, }, _addClasses: function() { var base = this; $(document.body).addClass('reveal-content'); // Keep subnav open if submenu item is active $('li.wsite-menu-subitem-wrap.wsite-nav-current').parents('.wsite-menu-wrap').addClass('open'); // Add placeholder text to inputs $('.wsite-form-sublabel').each(function(){ var sublabel = $(this).text(); $(this).prev('.wsite-form-input').attr('placeholder', sublabel); }); // Add fullwidth class to gallery thumbs if less than 6 $('.imageGallery').each(function(){ if ($(this).children('div').length <= 6) { $(this).children('div').addClass('fullwidth-mobile'); } }); }, _headerSetup: function() { var base = this; var $body = $(document.body); var $header = $('.edison-header'); var headerHeight; // Wait for redraw to happen after appending base._detectHeaderWrap(); headerHeight = $header.outerHeight(); if ($body.hasClass('header-sticky-up')) { base._utils.onScrollDirection({ down: function(currentScrollTop) { $header .removeClass('is-visible') .toggleClass('is-sticky', (currentScrollTop > headerHeight * 2)); base._closeAllDropdowns(); }, up: function() { $header.addClass('is-visible'); }, }); } if ($body.hasClass('header-sticky')) { $(window).on('scroll', function() { $body.toggleClass('header-compressed', $(this).scrollTop() > headerHeight * 2); }); } }, _detectHeaderWrap: function() { var headerHeight = $('.edison-header').outerHeight(); $('body').toggleClass('header-multiline', (headerHeight > 100)); // No logo if ($('.wsite-logo').children('.wsite-title-placeholder').length) { $('body').addClass('logo-hidden'); } // No Utils $.fn.intervalLoop('', function() { if ((!$('.wsite-search').length || $('.wsite-search').attr('style') === 'display: none;') && !$('#wsite-nav-cart-a').text().length) { $('body').addClass('utils-hidden'); } else { $('body').removeClass('utils-hidden'); } if ($('#wsite-nav-cart-a').length) { var cartText = $('#wsite-nav-cart-a').html().replace(/["'()]/g,""); $('#wsite-nav-cart-a').html(cartText).addClass("toggle-custom"); } if ($('.header-sticky:not(.header-compressed)').length || $('body').hasClass('header-sticky-up')) { headerHeight = $('.edison-header').outerHeight(); $('body').css({ paddingTop: headerHeight }); } }, 500, 8); }, _moveUtils: function() { var base = this; var winWidth = window.innerWidth; var $login = $('#member-login'); var $search = $('.wsite-search-wrap'); var search = $("#wsite-header-search-form input").clone(false); if (winWidth >= base._breakpoints.small) { $login.appendTo('.desktop-nav .wsite-menu-default'); $search.prependTo('.site-utils'); } else { $login.appendTo('.mobile-nav .wsite-menu-default'); $search.prependTo('.mobile-nav'); $('.wsite-search').show(); } base._observeDom($('.dummy-menu')[0], function(observer, target, config, mutation) { // Remove the duplicate login link after it is added if (mutation.addedNodes[0] === undefined || mutation.addedNodes[0].id !== 'member-login') return; $('.dummy-menu #member-login').remove(); }, { subtree: true }); }, _navSetup: function() { var base = this; var $submenuContainer = $('.nav .has-submenu'); var dropdownClass = 'dropdown-open'; var $desktopNav = $('.desktop-nav .wsite-menu-default'); var bindNavEvents = function() { $('.nav .has-submenu').each(function() { $(this) .off('click') .children('a') .off('click') .on('click.edison', function(event) { // Toggle submenu $(this) .parent() .toggleClass(dropdownClass) .children('.wsite-menu-wrap') .revealer('toggle'); // Hide children of other main nav items on desktop if (!$('.hamburger').is(':visible')) { $(this) .closest('li') .siblings('.has-submenu') .hideDropdowns(dropdownClass); } return false; }); }); $('.cloned-link > a').off('click.edison'); } if (typeof DISABLE_NAV_MORE == 'undefined' || !DISABLE_NAV_MORE) { $desktopNav.pxuMenu({ moreLinkHtml: 'More ', }); $.fn.intervalLoop('', function() { if ($desktopNav.data('pxuMenu')) { $desktopNav.data('pxuMenu').update(); bindNavEvents(); } }, 500, 5); } bindNavEvents(); // Unbind / bind after defaults have run base._observeDom($('.wsite-menu-default')[0], function() { bindNavEvents(); }, { subtree: true }); // Clone parent links into subnav $submenuContainer.each(function() { var $link = $(this).children('a'); if ($link.attr('href') === undefined || $link.hasClass('dead-link')) return; $link .parent() .clone() .removeClass('has-submenu wsite-menu-item-wrap') .addClass('wsite-menu-subitem-wrap cloned-link') .children('a') .removeClass('wsite-menu-item') .addClass('wsite-menu-subitem') .parent() .prependTo($link.next('.wsite-menu-wrap').children('.wsite-menu')); $('.cloned-link').find('.wsite-menu-wrap').remove(); }); // Close dropdowns if clicking outside nav $(document).on('click', function(event) { if ($(event.target).closest('.nav-wrap').length) { event.stopPropagation(); } else { base._closeAllDropdowns(); } }); // Close dropdowns on esc base._utils.onEscKey(function() { if (!$('.dropdown-open').length) return; base._closeAllDropdowns(); }); }, _closeAllDropdowns: function() { $('.edison-header') .find('.dropdown-open') .hideDropdowns('dropdown-open'); }, _searchBox: function() { var base = this; var searchBox = '.wsite-search'; // Not available in editor on doc ready var $searchToggle = $('.search-toggle'); var searchPosition = $searchToggle.outerHeight() + $searchToggle.offset().top; var searchText = $(".wsite-search-input").attr("placeholder"); var winWidth = window.innerWidth; $("#icontent .wsite-search").attr('data-search-text', searchText); $searchToggle.text(searchText); if (winWidth >= base._breakpoints.small) { // Make sure the editor also gets the class $.fn.intervalLoop('', function() { if ($('.wsite-search').attr('style') === 'display: none;') return; $('body').toggleClass('has-site-search', !!$('.wsite-search').length); }, 800, 5); $(searchBox) .css({top: searchPosition}) .on('revealer-show', function() { $(searchBox).find('.wsite-search-input').focus(); }) .find('.wsite-search-input') .attr('placeholder', $(".wsite-search-input").attr("placeholder")) .on('blur', function() { setTimeout(function() { $(searchBox).revealer('hide'); }, 300); }); base._utils.onEscKey(function() { if ($(searchBox).revealer('isVisible')) { $(searchBox).revealer('hide'); } }); $searchToggle.on('click', function(event) { event.preventDefault(); $(searchBox).revealer('toggle'); }); } }, _miniCartSetup: function() { var base = this; var $minicart = $('#wsite-mini-cart'); var cartOpenClass = 'mini-cart-open'; var toggleMiniCart = function(state) { var revealerState = state ? 'show' : 'hide'; $('body').toggleClass(cartOpenClass, state); $('.mini-cart-overlay').revealer(revealerState); }; var hijackMinicart = function() { var toggleText = $('#wsite-nav-cart-a').html().replace(/["'()]/g,""); $('#wsite-nav-cart-a') .html(toggleText) .off('click mouseenter mouseover mouseleave mouseout'); $('#wsite-mini-cart') .off('mouseenter mouseover mouseleave mouseout') .removeClass('arrow-top') .removeAttr('style') .prepend($('.mini-cart-header')); $('.mini-cart-toggle').toggleClass('has-mini-cart', !!$('.mini-cart-toggle').children().length); // Update responsive menu since site-utils dimesions will change if (typeof DISABLE_NAV_MORE == 'undefined' || !DISABLE_NAV_MORE) { $('.desktop-nav .wsite-menu-default').data('pxuMenu').update(); } }; var hijackMinicartToggle = function() { var $toggle = $('#wsite-nav-cart-a'); var toggleText = $toggle.html().replace(/["'()]/g,""); var itemCount = parseInt($('#wsite-nav-cart-num').text(), 10); var hasItems = isNaN(itemCount) || itemCount === 0 ? false : true; $toggle .html(toggleText) .addClass('toggle-custom') .off('click mouseenter mouseover mouseleave mouseout'); setTimeout(function() { $toggle.toggleClass('has-items', hasItems); }, 100); }; $(document).on('click', '.wsite-nav-cart', function() { toggleMiniCart(true); }); $(document).on('click', '.button-mini-cart-close, .mini-cart-overlay', function() { toggleMiniCart(false); }); base._utils.onEscKey(function() { if ($('body').hasClass(cartOpenClass)) { toggleMiniCart(false); } }); // Watch for minicart base._observeDom(document, function(docObserver, target, config) { // Bail if minicart not available yet if (!$('#wsite-mini-cart').length || !$('#wsite-nav-cart-a').length) return; // Watch minicart base._observeDom($('#wsite-mini-cart')[0], function(observer, target, config) { // Disconnect before making changes observer.disconnect(); // Unbind default handlers etc. hijackMinicart(); // Start watching again (for add / remove of items etc.) observer.observe(target, config); }); // Watch toggle for childList changes (ie. when the text changes) base._observeDom($('#wsite-nav-cart-a')[0], function(observer, target, config, mutation) { observer.disconnect(); hijackMinicartToggle(); observer.observe(target, config); }, { attributes: false, characterData: false }); // $minicart available, so stop watching the doc docObserver.disconnect(); }, { subtree: true }); }, _productSetup: function() { $('.product-grid-layout--above, .product-grid-layout--below').find('.product-grid__item').each(function() { var $product = $(this); $product.find('.product-grid__button').prependTo($product.find('.product-grid__images')); }); }, _attachEvents: function() { var base = this; // Nav toggle $('.hamburger').on('click', function() { $('body').toggleClass('nav-open'); $('.mobile-nav').revealer('toggle'); }); // Store category dropdown $('.wsite-com-sidebar').expandableSidebar('sidebar-expanded'); // Search filters dropdown $('#wsite-search-sidebar').expandableSidebar('sidebar-expanded'); // Init fancybox swipe on mobile if ('ontouchstart' in window) { $('body').on('click', 'a.w-fancybox', function() { base._initSwipeGallery(); }); } }, _initSwipeGallery: function() { var base = this; setTimeout(function(){ var touchGallery = document.getElementsByClassName('fancybox-wrap')[0]; var mc = new Hammer(touchGallery); mc.on("panleft panright", function(ev) { if (ev.type == "panleft") { $("a.fancybox-next").trigger("click"); } else if (ev.type == "panright") { $("a.fancybox-prev").trigger("click"); } base._initSwipeGallery(); }); }, 500); }, _observeDom: function(target, callback, config) { var config = $.extend({ attributes: true, childList: true, characterData: true }, config); // create an observer instance & callback var observer = new MutationObserver(function(mutations) { // Using every() instead of forEach() allows us to short-circuit the observer in the callback mutations.every(function(mutation) { callback(observer, target, config, mutation); }); }); // pass in the target node, as well as the observer options observer.observe(target, config); } } $(document).ready(function(){ edisonController.init(); }); });