jumper-8.x-1.1/js/src/jumper.load.js
js/src/jumper.load.js
/**
* @file
* Provides jumper loader for the Jumper block.
*/
(function ($, Drupal, drupalSettings, _win, _doc) {
'use strict';
var _name = 'jumper';
var _idOnce = _name;
var _ootb = _name + '--ootb';
var _mounted = _name + '--on';
var _element = '.' + _name;
var _dblclick = 'dblclick';
/**
* Jumper public methods.
*
* @namespace
*/
Drupal.jumper = {
/**
* Last scrollTop position.
*/
lastPos: 0,
/**
* Trigger jumper visibility when scrolled to the designated position.
*
* We don't need requestAnimationFrame as nobody don't animate classes.
*/
doScroll: function () {
var me = this;
var className = 'is-' + _name + '-visible';
var docEl = _doc.documentElement || _doc.body;
var yPos = _win.pageYOffset;
var pos = (yPos === 'undefined') ? docEl.scrollTop : yPos;
var visiblePoint = drupalSettings.jumper.visibility || 620;
// Scrolls down: show the jumper.
if (pos > me.lastPos) {
if (pos > visiblePoint && !$.hasClass(docEl, className)) {
$.addClass(docEl, className);
}
}
// Scrolls up: hide the jumper.
if (pos < me.lastPos) {
if (pos < visiblePoint && $.hasClass(docEl, className)) {
$.removeClass(docEl, className);
}
}
me.lastPos = pos;
}
};
/**
* Jumper utility functions.
*
* @param {HTMLElement} elm
* The jumper HTML element.
*/
function process(elm) {
var headerOffset = drupalSettings.jumper.offset || 100;
function doJump(target) {
if ('Jump' in _win) {
new Jump(target, {
duration: drupalSettings.jumper.duration,
offset: headerOffset
});
}
else {
target = $.find(_doc, target);
var elementPosition = target.offsetTop;
var offsetPosition = elementPosition - headerOffset;
_win.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
}
}
function doClick(e) {
e.preventDefault();
var btn = this;
var dataAttr = $.attr(btn, 'data-target');
var target = dataAttr || e.target.hash;
var isBlock = $.hasClass(btn, _name + '--block');
// Prevents unintended link hijacking when no target.
if (!target) {
return true;
}
if (isBlock && e.type === _dblclick) {
return true;
}
doJump(target);
}
$.on(elm, 'click', doClick);
$.on(elm, _dblclick, doClick);
$.addClass(elm, _mounted);
}
/**
* Attaches jumper behavior to HTML element identified by .jumper.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.jumper = {
attach: function (context) {
var me = Drupal.jumper;
var jumper = $.find(_doc, '#' + _name);
// Nothing to work with without a jumper block, bail out.
if (!$.isElm(jumper)) {
return;
}
// Makes jumper visible when scrolled to the designated position.
var onScroll = Drupal.debounce(me.doScroll.bind(me), 250);
$.on(_win, 'scroll', onScroll, {passive: true});
// Base CSS selector.
var jumpers = _element;
var extras = drupalSettings.jumper.selectors;
var block = $.find(_doc.body, '> #' + _name);
// Custom CSS selectors for easy additions without template overrides.
if (extras) {
jumpers += ', ' + extras.trim();
}
if ($.hasClass(jumper, _ootb) && !$.isElm(block)) {
$.removeClass(jumper, _ootb);
_doc.body.appendChild(jumper);
}
var elms = $.findAll(context, jumpers);
if (elms.length) {
// Simplify and unify selectors.
$.each(elms, function (el) {
if (!$.hasClass(el, _name)) {
$.addClass(el, _name);
}
});
$.once(process, _idOnce, _element + ':not(.' + _mounted + ')', context);
}
},
detach: function (context, settings, trigger) {
if (trigger === 'unload') {
$.once.removeSafely(_idOnce, _element, context);
}
}
};
})(dBlazy, Drupal, drupalSettings, this, this.document);
