From 13d9ca20576dc614e5a4c686f153079bbed7c95a Mon Sep 17 00:00:00 2001 From: Nicolas Coden Date: Fri, 23 Mar 2018 10:01:56 +0100 Subject: [PATCH] fix: refactor the `onLoad` uility to allow to unbind the created listenner --- js/foundation.accordion.js | 2 +- js/foundation.magellan.js | 25 +++++++++++++++---------- js/foundation.offcanvas.js | 3 ++- js/foundation.reveal.js | 6 ++++-- js/foundation.sticky.js | 6 ++++-- js/foundation.tabs.js | 3 ++- js/foundation.util.core.js | 31 +++++++++++++++++++++++-------- js/foundation.util.triggers.js | 2 +- 8 files changed, 52 insertions(+), 26 deletions(-) diff --git a/js/foundation.accordion.js b/js/foundation.accordion.js index 81d8f0aa8..282a2a54a 100644 --- a/js/foundation.accordion.js +++ b/js/foundation.accordion.js @@ -82,7 +82,7 @@ class Accordion extends Plugin { //roll up a little to show the titles if (this.options.deepLinkSmudge) { var _this = this; - onLoad(function() { + onLoad($(window), function() { var offset = _this.$element.offset(); $('html, body').animate({ scrollTop: offset.top }, _this.options.deepLinkSmudgeDelay); }); diff --git a/js/foundation.magellan.js b/js/foundation.magellan.js index 7878a7ab9..001d1dadd 100644 --- a/js/foundation.magellan.js +++ b/js/foundation.magellan.js @@ -94,15 +94,17 @@ class Magellan extends Plugin { _this._updateActive(); }); - onLoad(function () { - _this.$element.on({ - 'resizeme.zf.trigger': _this.reflow.bind(_this), - 'scrollme.zf.trigger': _this._updateActive.bind(_this) - }).on('click.zf.magellan', 'a[href^="#"]', function (e) { - e.preventDefault(); - var arrival = _this.getAttribute('href'); - _this.scrollToLoc(arrival); - }); + _this.onLoadListener = onLoad($(window), function () { + _this.$element + .on({ + 'resizeme.zf.trigger': _this.reflow.bind(_this), + 'scrollme.zf.trigger': _this._updateActive.bind(_this) + }) + .on('click.zf.magellan', 'a[href^="#"]', function (e) { + e.preventDefault(); + var arrival = _this.getAttribute('href'); + _this.scrollToLoc(arrival); + }); }); this._deepLinkScroll = function(e) { @@ -224,7 +226,10 @@ class Magellan extends Plugin { var hash = this.$active[0].getAttribute('href'); window.location.hash.replace(hash, ''); } - $(window).off('hashchange', this._deepLinkScroll); + + $(window) + .off('hashchange', this._deepLinkScroll) + .off(this.onLoadListener); } } diff --git a/js/foundation.offcanvas.js b/js/foundation.offcanvas.js index 12caff509..150b35ac2 100644 --- a/js/foundation.offcanvas.js +++ b/js/foundation.offcanvas.js @@ -166,7 +166,7 @@ class OffCanvas extends Plugin { _setMQChecker() { var _this = this; - onLoad(function () { + this.onLoadListener = onLoad($(window), function () { if (MediaQuery.atLeast(_this.options.revealOn)) { _this.reveal(true); } @@ -447,6 +447,7 @@ class OffCanvas extends Plugin { this.close(); this.$element.off('.zf.trigger .zf.offCanvas'); this.$overlay.off('.zf.offCanvas'); + $(window).off(this.onLoadListener); } } diff --git a/js/foundation.reveal.js b/js/foundation.reveal.js index 85230af3e..8c213ca62 100644 --- a/js/foundation.reveal.js +++ b/js/foundation.reveal.js @@ -79,7 +79,7 @@ class Reveal extends Plugin { } this._events(); if (this.options.deepLink && window.location.hash === ( `#${this.id}`)) { - onLoad(() => this.open()); + this.onLoadListener = onLoad($(window), () => this.open()); } } @@ -472,7 +472,9 @@ class Reveal extends Plugin { } this.$element.hide().off(); this.$anchor.off('.zf'); - $(window).off(`.zf.reveal:${this.id}`); + $(window) + .off(`.zf.reveal:${this.id}`) + .off(this.onLoadListener); if ($('.reveal:visible').length === 0) { this._removeRevealOpenClasses(); // also remove .is-reveal-open from the html element when there is no opened reveal diff --git a/js/foundation.sticky.js b/js/foundation.sticky.js index 28c6a8548..b95eccd8a 100644 --- a/js/foundation.sticky.js +++ b/js/foundation.sticky.js @@ -60,7 +60,7 @@ class Sticky extends Plugin { this.scrollCount = this.options.checkEvery; this.isStuck = false; - onLoad(function () { + this.onLoadListener = onLoad($(window), function () { //We calculate the container height to have correct values for anchor points offset calculation. _this.containerHeight = _this.$element.css("display") == "none" ? 0 : _this.$element[0].getBoundingClientRect().height; _this.$container.css('height', _this.containerHeight); @@ -403,7 +403,9 @@ class Sticky extends Plugin { if (this.$anchor && this.$anchor.length) { this.$anchor.off('change.zf.sticky'); } - $(window).off(this.scrollListener); + $(window) + .off(this.scrollListener) + .off(this.onLoadListener); if (this.wasWrapped) { this.$element.unwrap(); diff --git a/js/foundation.tabs.js b/js/foundation.tabs.js index ab8b6a463..1b32f890c 100644 --- a/js/foundation.tabs.js +++ b/js/foundation.tabs.js @@ -78,7 +78,7 @@ class Tabs extends Plugin { } if(isActive && _this.options.autoFocus){ - onLoad(function() { + _this.onLoadListener = onLoad($(window), function() { $('html, body').animate({ scrollTop: $elem.offset().top }, _this.options.deepLinkSmudgeDelay, () => { $link.focus(); }); @@ -398,6 +398,7 @@ class Tabs extends Plugin { $(window).off('hashchange', this._checkDeepLink); } + $(window).off(this.onLoadListener); } } diff --git a/js/foundation.util.core.js b/js/foundation.util.core.js index 1c01ae03c..c70f989d5 100644 --- a/js/foundation.util.core.js +++ b/js/foundation.util.core.js @@ -62,17 +62,32 @@ function transitionend($elem){ } /** - * Call the given function once the window is loaded, - * or immediately if the window is already loaded. + * Return an event type to listen for window load. + * + * If `$elem` is passed, an event will be triggered on `$elem`. If window is already loaded, the event will still be triggered. + * If `handler` is passed, attach it to the event on `$elem`. + * Calling `onLoad` without handler allows you to get the event type that will be triggered before attaching the handler by yourself. * @function * - * @param {Function} fn - function to call on window load. + * @param {Object} [] $elem - jQuery element on which the event will be triggered if passed. + * @param {Function} [] handler - function to attach to the event. + * @returns {String} - event type that should or will be triggered. */ -function onLoad(fn) { - if (document.readyState === 'complete') - setTimeout(() => fn(), 0); - else - $(window).one('load', () => fn()); +function onLoad($elem, handler) { + const didLoad = document.readyState === 'complete'; + const eventType = (didLoad ? '_didLoad' : 'load') + '.zf.util.onLoad'; + const cb = () => $elem.triggerHandler(eventType); + + if ($elem) { + if (handler) $elem.one(eventType, handler); + + if (didLoad) + setTimeout(cb); + else + $(window).one('load', cb); + } + + return eventType; } export {rtl, GetYoDigits, RegExpEscape, transitionend, onLoad}; diff --git a/js/foundation.util.triggers.js b/js/foundation.util.triggers.js index 1a59773e6..ed717f14f 100644 --- a/js/foundation.util.triggers.js +++ b/js/foundation.util.triggers.js @@ -245,7 +245,7 @@ Triggers.init = function($, Foundation) { if (typeof($.triggersInitialized) === 'undefined') { let $document = $(document); - onLoad(function () { + onLoad($(window), function () { Triggers.Initializers.addSimpleListeners(); Triggers.Initializers.addGlobalListeners(); }); -- 2.47.2