IMPR: AJAX online/offline handling

This commit is contained in:
Tony Air 2020-09-11 02:48:14 +07:00
parent bcc4a131ce
commit 59af7f47fe
6 changed files with 535 additions and 520 deletions

2
dist/js/app.js vendored

File diff suppressed because one or more lines are too long

2
dist/js/app.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{ {
"name": "@a2nt/ss-bootstrap-ui-webpack-boilerplate", "name": "@a2nt/ss-bootstrap-ui-webpack-boilerplate",
"version": "2.5.2", "version": "2.5.3",
"author": "Tony Air <tony@twma.pro>", "author": "Tony Air <tony@twma.pro>",
"license": "MIT", "license": "MIT",
"description": "This UI Kit allows you to build Bootstrap 4 webapp with some extra UI features. It's easy to extend and easy to convert HTML templates to CMS templates.", "description": "This UI Kit allows you to build Bootstrap 4 webapp with some extra UI features. It's easy to extend and easy to convert HTML templates to CMS templates.",

View File

@ -286,7 +286,7 @@ const AjaxUI = (($) => {
for (const url in $.xhrPool.requests) { for (const url in $.xhrPool.requests) {
const jqXHR = $.xhrPool.requests[url]; const jqXHR = $.xhrPool.requests[url];
$.ajax(jqXHR.opts); $.ajax(jqXHR.opts);
//console.log(`${NAME}: AJAX request is restored (${jqXHR.opts.url})`); console.log(`${NAME}: AJAX request is restored (${jqXHR.opts.url})`);
} }
$.xhrPool.paused = false; $.xhrPool.paused = false;
@ -308,7 +308,7 @@ const AjaxUI = (($) => {
$.xhrPool.pauseAll(); $.xhrPool.pauseAll();
}); });
$Body.on(`${Events.ONLINE}`, () => { $Body.on(`${Events.BACKONLINE}`, () => {
$.xhrPool.restoreAll(); $.xhrPool.restoreAll();
}); });

View File

@ -10,6 +10,7 @@ module.exports = {
TABFOCUSED: 'tab-focused', TABFOCUSED: 'tab-focused',
OFFLINE: 'offline', OFFLINE: 'offline',
ONLINE: 'online', ONLINE: 'online',
BACKONLINE: 'back-online',
TOUCHENABLE: 'touch-enabled', TOUCHENABLE: 'touch-enabled',
TOUCHDISABLED: 'touch-disabled', TOUCHDISABLED: 'touch-disabled',
LOADED: 'load', LOADED: 'load',

View File

@ -18,199 +18,218 @@ import SmoothScroll from 'smooth-scroll';
const smoothScroll = SmoothScroll(); const smoothScroll = SmoothScroll();
const MainUI = (($) => { const MainUI = (($) => {
// Constants // Constants
const W = window; const W = window;
const $W = $(W); const $W = $(W);
const D = document; const D = document;
const $Body = $('body'); const $Body = $('body');
const NAME = 'MainUI'; const NAME = 'MainUI';
console.clear(); console.clear();
console.info( console.info(
`%cUI Kit ${UINAME} ${UIVERSION}`, `%cUI Kit ${UINAME} ${UIVERSION}`,
'color:yellow;font-size:14px', 'color:yellow;font-size:14px',
); );
console.info( console.info(
`%c${UIMetaNAME} ${UIMetaVersion}`, `%c${UIMetaNAME} ${UIMetaVersion}`,
'color:yellow;font-size:12px', 'color:yellow;font-size:12px',
); );
console.info( console.info(
`%chttps://github.com/a2nt/webpack-bootstrap-ui-kit by ${UIAUTHOR}`, `%chttps://github.com/a2nt/webpack-bootstrap-ui-kit by ${UIAUTHOR}`,
'color:yellow;font-size:10px', 'color:yellow;font-size:10px',
); );
console.groupCollapsed('Events'); console.groupCollapsed('Events');
Object.keys(Events).forEach((k) => { Object.keys(Events).forEach((k) => {
console.info(`${k}: ${Events[k]}`); console.info(`${k}: ${Events[k]}`);
}); });
console.groupEnd('Events'); console.groupEnd('Events');
console.groupCollapsed('Consts'); console.groupCollapsed('Consts');
Object.keys(Consts).forEach((k) => { Object.keys(Consts).forEach((k) => {
console.info(`${k}: ${Consts[k]}`); console.info(`${k}: ${Consts[k]}`);
}); });
console.groupEnd('Events'); console.groupEnd('Events');
console.groupCollapsed('Init'); console.groupCollapsed('Init');
console.time('init'); console.time('init');
$W.on(`${Events.LODEDANDREADY}`, () => { $W.on(`${Events.LODEDANDREADY}`, () => {
console.groupEnd('Init'); console.groupEnd('Init');
console.timeEnd('init'); console.timeEnd('init');
console.time('Post-init'); console.time('Post-init');
console.groupCollapsed('Post-init'); console.groupCollapsed('Post-init');
}); });
// get browser locale // get browser locale
//const Locale = $('html').attr('lang').substring(0, 2); //const Locale = $('html').attr('lang').substring(0, 2);
const $AlertNotify = $('#AlertNotify'); const $AlertNotify = $('#AlertNotify');
const $SiteWideMessage = $('#SiteWideMessage'); const $SiteWideMessage = $('#SiteWideMessage');
// get browser window visibility preferences // get browser window visibility preferences
// Opera 12.10, Firefox >=18, Chrome >=31, IE11 // Opera 12.10, Firefox >=18, Chrome >=31, IE11
const HiddenName = 'hidden'; const HiddenName = 'hidden';
const VisibilityChangeEvent = 'visibilitychange'; const VisibilityChangeEvent = 'visibilitychange';
// update visibility state // update visibility state
D.addEventListener(VisibilityChangeEvent, () => { D.addEventListener(VisibilityChangeEvent, () => {
if (D.visibilityState === HiddenName) { if (D.visibilityState === HiddenName) {
console.log(`${NAME}: Tab: hidden`); console.log(`${NAME}: Tab: hidden`);
$Body.addClass('is-hidden'); $Body.addClass('is-hidden');
$Body.trigger(Events.TABHIDDEN); $Body.trigger(Events.TABHIDDEN);
$W.trigger(Events.TABHIDDEN); $W.trigger(Events.TABHIDDEN);
} else { } else {
console.log(`${NAME}: Tab: focused`); console.log(`${NAME}: Tab: focused`);
$Body.removeClass('is-hidden'); $Body.removeClass('is-hidden');
$Body.trigger(Events.TABFOCUSED); $Body.trigger(Events.TABFOCUSED);
$W.trigger(Events.TABFOCUSED); $W.trigger(Events.TABFOCUSED);
} }
}); });
// session ping // session ping
const sessionPing = () => { let pingInterval;
if ($Body.hasClass('is-offline')) { let pingLock = false;
return; const sessionPing = () => {
} if (pingLock || $Body.hasClass('is-offline')) {
return;
}
console.log(`${NAME}: session ping`); console.log(`${NAME}: session ping`);
pingLock = true;
$.ajax({
sync: false,
async: true,
cache: false,
url: '/Security/ping',
global: false,
type: 'POST',
complete: (data, datastatus) => {
updateOnlineStatus();
if (datastatus !== 'success') {
console.warn(`${NAME}: ping failed`);
$.ajax({ clearInterval(pingInterval);
sync: false, pingInterval = null;
async: true, }
cache: false,
url: '/Security/ping',
global: false,
type: 'POST',
complete: (data, datastatus) => {
if (datastatus !== 'success') {
console.warn(`${NAME}: ping failed`);
clearInterval(pingInterval);
}
updateOnlineStatus();
},
});
};
let pingInterval = setInterval(sessionPing, 300000); // 5 min in ms pingLock = false;
},
});
};
// update online/offline state // update online/offline state
const updateOnlineStatus = () => { const updateOnlineStatus = () => {
if (typeof navigator.onLine === 'undefined') { if (typeof navigator.onLine === 'undefined') {
return; return false;
} }
if (!navigator.onLine) {
console.log(`${NAME}: Tab: offline`);
clearInterval(pingInterval);
$Body.addClass('is-offline'); if (!navigator.onLine) {
$Body.trigger(Events.OFFLINE); console.log(`${NAME}: Tab: offline`);
$W.trigger(Events.OFFLINE);
} else {
console.log(`${NAME}: Tab: online`);
pingInterval = setInterval(sessionPing, 300000); // 5 min in ms
$Body.removeClass('is-offline'); clearInterval(pingInterval);
$Body.trigger(Events.ONLINE); pingInterval = null;
$W.trigger(Events.ONLINE);
}
};
W.addEventListener( $Body.addClass('is-offline');
`${Events.OFFLINE}`, $Body.removeClass('is-online');
() => {
updateOnlineStatus();
},
false,
);
W.addEventListener( $Body.trigger(Events.OFFLINE);
`${Events.ONLINE}`, $W.trigger(Events.OFFLINE);
() => {
updateOnlineStatus();
},
false,
);
W.addEventListener(`${Events.LOADED}`, () => { return true;
updateOnlineStatus(); }
});
$W.on(`${Events.AJAX}`, () => { if (!pingInterval) {
updateOnlineStatus(); pingInterval = setInterval(sessionPing, 300000); // 5 min in ms
}); }
// scrollTo console.log(`${NAME}: Tab: online`);
const ScrollTo = (trigger, selector) => { if ($Body.hasClass('is-offline')) {
smoothScroll.animateScroll(D.querySelector(selector), trigger, { sessionPing();
speed: 500,
offset: -20,
//easing: 'easeInOutCubic',
// Callback API
//before: (anchor, toggle) => {}, // Callback to run before scroll
//`after: (anchor, toggle) => {} // Callback to run after scroll
});
};
W.URLDetails = { $Body.trigger(Events.BACKONLINE);
base: $('base').attr('href'), }
relative: '/',
hash: '',
};
let eventFired = false; $Body.addClass('is-online');
const setTouchScreen = (bool) => { $Body.removeClass('is-offline');
if (W.IsTouchScreen === bool || eventFired) {
return;
}
eventFired = true; $Body.trigger(Events.ONLINE);
$W.trigger(Events.ONLINE);
W.IsTouchScreen = bool; return true;
$.support.touch = W.IsTouchScreen; };
if (bool) { W.addEventListener(
console.log(`${NAME}: Touch screen enabled`); `${Events.OFFLINE}`,
$Body.trigger(Events.TOUCHENABLE); () => {
$W.trigger(Events.TOUCHENABLE); updateOnlineStatus();
} else { },
console.log(`${NAME}: Touch screen disabled`); false,
$Body.trigger(Events.TOUCHDISABLED); );
$W.trigger(Events.TOUCHDISABLED);
}
// prevent firing touch and mouse events together W.addEventListener(
setTimeout(() => { `${Events.ONLINE}`,
eventFired = false; () => {
}, 200); updateOnlineStatus();
}; },
false,
);
setTouchScreen('ontouchstart' in window || navigator.msMaxTouchPoints > 0); $W.on(`${Events.LOADED} ${Events.AJAX}`, () => {
updateOnlineStatus();
});
// disable touch on mouse events // scrollTo
/*D.addEventListener('mousemove', () => { const ScrollTo = (trigger, selector) => {
smoothScroll.animateScroll(D.querySelector(selector), trigger, {
speed: 500,
offset: -20,
//easing: 'easeInOutCubic',
// Callback API
//before: (anchor, toggle) => {}, // Callback to run before scroll
//`after: (anchor, toggle) => {} // Callback to run after scroll
});
};
W.URLDetails = {
base: $('base').attr('href'),
relative: '/',
hash: '',
};
let eventFired = false;
const setTouchScreen = (bool) => {
if (W.IsTouchScreen === bool || eventFired) {
return;
}
eventFired = true;
W.IsTouchScreen = bool;
$.support.touch = W.IsTouchScreen;
if (bool) {
console.log(`${NAME}: Touch screen enabled`);
$Body.trigger(Events.TOUCHENABLE);
$W.trigger(Events.TOUCHENABLE);
} else {
console.log(`${NAME}: Touch screen disabled`);
$Body.trigger(Events.TOUCHDISABLED);
$W.trigger(Events.TOUCHDISABLED);
}
// prevent firing touch and mouse events together
setTimeout(() => {
eventFired = false;
}, 200);
};
setTouchScreen('ontouchstart' in window || navigator.msMaxTouchPoints > 0);
// disable touch on mouse events
/*D.addEventListener('mousemove', () => {
setTouchScreen(false); setTouchScreen(false);
}); });
@ -218,41 +237,41 @@ const MainUI = (($) => {
setTouchScreen(false); setTouchScreen(false);
});*/ });*/
// enable touch screen on touch events // enable touch screen on touch events
D.addEventListener('touchmove', () => { D.addEventListener('touchmove', () => {
setTouchScreen(true); setTouchScreen(true);
}); });
D.addEventListener('touchstart', () => { D.addEventListener('touchstart', () => {
setTouchScreen(true); setTouchScreen(true);
}); });
class MainUI { class MainUI {
// Static methods // Static methods
static init() { static init() {
const ui = this; const ui = this;
ui.dispose(); ui.dispose();
console.log(`${NAME}: init`); console.log(`${NAME}: init`);
// update location details // update location details
ui.updateLocation(); ui.updateLocation();
// mark available offline areas // mark available offline areas
if ('caches' in W) { if ('caches' in W) {
$('a.offline').addClass('offline-available'); $('a.offline').addClass('offline-available');
} }
ui.loadImages(); ui.loadImages();
// detect bootstrap screen size // detect bootstrap screen size
ui.detectBootstrapScreenSize(); ui.detectBootstrapScreenSize();
// mark external links // mark external links
$('a.external,a[rel="external"]').attr('target', '_blank'); $('a.external,a[rel="external"]').attr('target', '_blank');
// show encoded emails // show encoded emails
/*$(D).find('.obm').each(() => { /*$(D).find('.obm').each(() => {
if ($(this).attr('data-val') !== undefined) { if ($(this).attr('data-val') !== undefined) {
const email = $(this).attr('data-val').split('') const email = $(this).attr('data-val').split('')
.reverse() .reverse()
@ -272,333 +291,328 @@ const MainUI = (($) => {
} }
} }
});*/ });*/
// //
// scroll links // scroll links
$('.js-scrollTo').on('click', (e) => { $('.js-scrollTo').on('click', (e) => {
console.log(`${NAME}: .js-scrollTo`); console.log(`${NAME}: .js-scrollTo`);
e.preventDefault(); e.preventDefault();
const el = e.currentTarget; const el = e.currentTarget;
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
ScrollTo(el, $el.attr('data-target')); ScrollTo(el, $el.attr('data-target'));
}); });
// load external fonts // load external fonts
if ($('[data-extfont]').length) { if ($('[data-extfont]').length) {
console.log(`${NAME}: loading external fonts [data-extfont]`); console.log(`${NAME}: loading external fonts [data-extfont]`);
$.getScript( $.getScript(
'//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js', '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js',
() => { () => {
const fonts = []; const fonts = [];
$('[data-extfont]').each((i, el) => { $('[data-extfont]').each((i, el) => {
fonts[i] = $(el).attr('data-extfont'); fonts[i] = $(el).attr('data-extfont');
}); });
W.WebFont.load({ W.WebFont.load({
google: { google: {
families: fonts, families: fonts,
}, },
}); });
}, },
); );
} }
// data-set links // data-set links
$('[data-set-target]').on('click', (e) => { $('[data-set-target]').on('click', (e) => {
console.log(`${NAME}: [data-set-target]`); console.log(`${NAME}: [data-set-target]`);
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
const $target = $($el.data('set-target')); const $target = $($el.data('set-target'));
if (!$target.length) { if (!$target.length) {
return; return;
} }
$target.each((i, targetEl) => { $target.each((i, targetEl) => {
const $targetEl = $(targetEl); const $targetEl = $(targetEl);
const tag = $targetEl.prop('tagName').toLowerCase(); const tag = $targetEl.prop('tagName').toLowerCase();
if (tag === 'input' || tag === 'select') { if (tag === 'input' || tag === 'select') {
$targetEl.val($el.data('set-val')); $targetEl.val($el.data('set-val'));
} else if (!$targetEl.hasClass('field')) { } else if (!$targetEl.hasClass('field')) {
$targetEl.text($el.data('set-val')); $targetEl.text($el.data('set-val'));
} }
}); });
$el.trigger(Events.SET_TARGET_UPDATE); $el.trigger(Events.SET_TARGET_UPDATE);
$target.closest('form').trigger(Events.SET_TARGET_UPDATE); $target.closest('form').trigger(Events.SET_TARGET_UPDATE);
}); });
// emulate links // emulate links
$('.a[data-href]').on('click', (e) => { $('.a[data-href]').on('click', (e) => {
console.log(`${NAME}: js link processing .a[data-href]`); console.log(`${NAME}: js link processing .a[data-href]`);
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
const href = $el.data('href'); const href = $el.data('href');
if (!href.length) { if (!href.length) {
console.warn(`${NAME}: .a[data-href] | Missing data-href`); console.warn(`${NAME}: .a[data-href] | Missing data-href`);
console.warn($el); console.warn($el);
} }
W.location.assign(href); W.location.assign(href);
}); });
// hide spinner // hide spinner
Spinner.hide(() => { Spinner.hide(() => {
$Body.addClass('loaded'); $Body.addClass('loaded');
}); });
// fire page printing // fire page printing
if (W.URLDetails['hash'].indexOf('printpage') > -1) { if (W.URLDetails['hash'].indexOf('printpage') > -1) {
W.print(); W.print();
} }
$Body.data(NAME, ui); $Body.data(NAME, ui);
$W.removeClass('lock-main-init'); $W.removeClass('lock-main-init');
} }
static detectBootstrapScreenSize() { static detectBootstrapScreenSize() {
const $el = $('<div class="env-test"></div>'); const $el = $('<div class="env-test"></div>');
let envs = [...Consts.ENVS]; let envs = [...Consts.ENVS];
$Body.append($el); $Body.append($el);
let curEnv = envs.shift(); let curEnv = envs.shift();
envs = envs.reverse(); envs = envs.reverse();
for (let i = 0; i < envs.length; ++i) { for (let i = 0; i < envs.length; ++i) {
const env = envs[i]; const env = envs[i];
$el.addClass(`d-${env}-none`); $el.addClass(`d-${env}-none`);
if ($el.is(':hidden')) { if ($el.is(':hidden')) {
curEnv = env; curEnv = env;
break; break;
} }
} }
$el.remove(); $el.remove();
$Body.removeClass(envs); $Body.removeClass(envs);
$Body.addClass(curEnv); $Body.addClass(curEnv);
let landscape = true; let landscape = true;
if ($W.width() > $W.height()) { if ($W.width() > $W.height()) {
$Body.removeClass('portrait'); $Body.removeClass('portrait');
$Body.addClass('landscape'); $Body.addClass('landscape');
} else { } else {
landscape = false; landscape = false;
$Body.removeClass('landscape'); $Body.removeClass('landscape');
$Body.addClass('portrait'); $Body.addClass('portrait');
} }
console.log( console.log(
`${NAME}: screen size detected ${curEnv} | landscape ${landscape}`, `${NAME}: screen size detected ${curEnv} | landscape ${landscape}`,
); );
return curEnv; return curEnv;
} }
static updateLocation(url) { static updateLocation(url) {
let location = url || W.location.href; let location = url || W.location.href;
location = location.replace(W.URLDetails['base'], '/'); location = location.replace(W.URLDetails['base'], '/');
const hash = location.indexOf('#'); const hash = location.indexOf('#');
W.URLDetails.relative = location.split('#')[0]; W.URLDetails.relative = location.split('#')[0];
W.URLDetails.hash = W.URLDetails.hash =
hash >= 0 ? location.substr(location.indexOf('#')) : ''; hash >= 0 ? location.substr(location.indexOf('#')) : '';
} }
// show site-wide alert // show site-wide alert
static alert(msg, cls) { static alert(msg, cls) {
$SiteWideMessage.fadeOut('fast'); $SiteWideMessage.fadeOut('fast');
$SiteWideMessage.html( $SiteWideMessage.html(
`<div class="page-alert"><div class="alert alert-${cls}"><i class="close" data-dismiss="alert">&times;</i>${msg}</div></div>`, `<div class="page-alert"><div class="alert alert-${cls}"><i class="close" data-dismiss="alert">&times;</i>${msg}</div></div>`,
); );
$SiteWideMessage.find('.page-alert').alert(); $SiteWideMessage.find('.page-alert').alert();
$SiteWideMessage.find('.close[data-dismiss="alert"]').click(() => { $SiteWideMessage.find('.close[data-dismiss="alert"]').click(() => {
$SiteWideMessage.fadeOut('slow', () => { $SiteWideMessage.fadeOut('slow', () => {
$SiteWideMessage.find('.page-alert').alert('close'); $SiteWideMessage.find('.page-alert').alert('close');
}); });
}); });
$SiteWideMessage.fadeIn('slow'); $SiteWideMessage.fadeIn('slow');
if ($AlertNotify.length) { if ($AlertNotify.length) {
$AlertNotify[0].play(); $AlertNotify[0].play();
} }
$W.trigger(`${Events.ALLERTAPPEARED}`); $W.trigger(`${Events.ALLERTAPPEARED}`);
} }
// hide site-wide alert // hide site-wide alert
static alertHide() { static alertHide() {
if ($SiteWideMessage.length !== 0) { if ($SiteWideMessage.length !== 0) {
$SiteWideMessage.fadeOut('slow', () => { $SiteWideMessage.fadeOut('slow', () => {
$SiteWideMessage.find('.alert').alert('close'); $SiteWideMessage.find('.alert').alert('close');
}); });
} }
if ( if ($AlertNotify.length && typeof $AlertNotify[0].stop !== 'undefined') {
$AlertNotify.length && $AlertNotify[0].stop();
typeof $AlertNotify[0].stop !== 'undefined' }
) {
$AlertNotify[0].stop(); $W.trigger(`${Events.ALLERTREMOVED}`);
} }
$W.trigger(`${Events.ALLERTREMOVED}`); // load all images
} static loadImages() {
const $imgs = $Body.find('img').not('.loaded');
// load all images const $imgUrls = [];
static loadImages() { const $imgLazyUrls = [];
const $imgs = $Body.find('img').not('.loaded');
const $imgUrls = []; // collect image details
const $imgLazyUrls = []; $imgs.each((i, el) => {
const $el = $(el);
// collect image details const src = $el.attr('src');
$imgs.each((i, el) => { const lazySrc = $el.data('lazy-src');
const $el = $(el);
const src = $el.attr('src'); if ($el.hasClass('loaded')) {
const lazySrc = $el.data('lazy-src'); return;
}
if ($el.hasClass('loaded')) {
return; if (src && src.length) {
} $imgUrls.push(src);
}
if (src && src.length) { if (lazySrc && lazySrc.length) {
$imgUrls.push(src); $imgLazyUrls.push(lazySrc);
} $el.addClass('loading');
if (lazySrc && lazySrc.length) {
$imgLazyUrls.push(lazySrc); AjaxUI.preload([lazySrc]).then(() => {
$el.addClass('loading'); $el.attr('src', lazySrc);
AjaxUI.preload([lazySrc]).then(() => { $el.on(`${Events.LOADED}`, () => {
$el.attr('src', lazySrc); $el.addClass('loaded');
$el.removeClass('loading');
$el.on(`${Events.LOADED}`, () => {
$el.addClass('loaded'); $el.trigger(`${Events.LAZYIMAGEREADY}`);
$el.removeClass('loading'); });
});
$el.trigger(`${Events.LAZYIMAGEREADY}`); }
}); });
});
} // load lazy backgrounds
}); $Body
.find('[data-lazy-bg]')
// load lazy backgrounds .not('.loaded')
$Body .each((i, el) => {
.find('[data-lazy-bg]') const $el = $(el);
.not('.loaded') const lazySrc = $el.data('lazy-bg');
.each((i, el) => {
const $el = $(el); if ($el.hasClass('loaded')) {
const lazySrc = $el.data('lazy-bg'); return;
}
if ($el.hasClass('loaded')) {
return; if (lazySrc && lazySrc.length) {
} $imgLazyUrls.push(lazySrc);
$el.addClass('loading');
if (lazySrc && lazySrc.length) {
$imgLazyUrls.push(lazySrc); AjaxUI.preload([lazySrc]).then(() => {
$el.addClass('loading'); $el.css({ 'background-image': `url(${lazySrc})` });
AjaxUI.preload([lazySrc]).then(() => { $el.addClass('loaded');
$el.css({ 'background-image': `url(${lazySrc})` }); $el.removeClass('loading');
$el.addClass('loaded'); $el.trigger(`${Events.LAZYIMAGEREADY}`);
$el.removeClass('loading'); });
}
$el.trigger(`${Events.LAZYIMAGEREADY}`); });
});
} // replace img src
}); $Body
.find('[data-src-replace]')
// replace img src .not('.loaded')
$Body .each((i, el) => {
.find('[data-src-replace]') const $el = $(el);
.not('.loaded') const lazySrc = $el.data('src-replace');
.each((i, el) => {
const $el = $(el); if ($el.hasClass('loaded')) {
const lazySrc = $el.data('src-replace'); return;
}
if ($el.hasClass('loaded')) {
return; if (lazySrc && lazySrc.length) {
} $el.addClass('loaded');
$el.attr('src', lazySrc);
if (lazySrc && lazySrc.length) { }
$el.addClass('loaded'); });
$el.attr('src', lazySrc);
} // load defined images
}); AjaxUI.preload($imgUrls).then(() => {
$W.trigger('images-loaded');
// load defined images
AjaxUI.preload($imgUrls).then(() => { // load lazy images
$W.trigger('images-loaded'); AjaxUI.preload($imgLazyUrls).then(() => {
console.log(`${NAME}: All images are loaded!`);
// load lazy images
AjaxUI.preload($imgLazyUrls).then(() => { setTimeout(() => {
console.log(`${NAME}: All images are loaded!`); $W.trigger(`${Events.LAZYIMAGESREADY}`);
setTimeout(() => { console.groupEnd('Post-init');
$W.trigger(`${Events.LAZYIMAGESREADY}`); console.timeEnd('Post-init');
}, 100);
console.groupEnd('Post-init'); });
console.timeEnd('Post-init'); });
}, 100); }
});
}); static dispose() {
} console.log(`${NAME}: dispose`);
}
static dispose() { }
console.log(`${NAME}: dispose`);
} $W.on(
} `${Events.MAININIT} ${Events.AJAX} ${Events.AJAXMAIN} ${Events.LOADED}`,
() => {
$W.on( if ($W.hasClass('lock-main-init')) {
`${Events.MAININIT} ${Events.AJAX} ${Events.AJAXMAIN} ${Events.LOADED}`, console.warn('MainUI is locked');
() => { return;
if ($W.hasClass('lock-main-init')) { }
console.warn('MainUI is locked');
return; $W.addClass('lock-main-init');
} MainUI.init();
},
$W.addClass('lock-main-init'); );
MainUI.init();
}, $W.on(`${Events.RESIZE}`, () => {
); MainUI.detectBootstrapScreenSize();
});
$W.on(`${Events.RESIZE}`, () => {
MainUI.detectBootstrapScreenSize(); $W.on('beforeunload unload', () => {
}); Spinner.show(() => {
$Body.removeClass('loaded');
$W.on('beforeunload unload', () => { });
Spinner.show(() => { });
$Body.removeClass('loaded');
}); // hide spinner on target _blank
}); $('[target="_blank"],.external').on('click submit', (e) => {
if (
// hide spinner on target _blank $(e.currentTarget).is('[data-toggle="lightbox"],[data-lightbox-gallery]')
$('[target="_blank"],.external').on('click submit', (e) => { ) {
if ( return false;
$(e.currentTarget).is( }
'[data-toggle="lightbox"],[data-lightbox-gallery]',
) console.log(`${NAME}: External link`);
) { setTimeout(() => {
return false; Spinner.hide(() => {
} $Body.addClass('loaded');
});
console.log(`${NAME}: External link`); }, 1000);
setTimeout(() => { });
Spinner.hide(() => {
$Body.addClass('loaded'); W.MainUI = MainUI;
});
}, 1000); return MainUI;
});
W.MainUI = MainUI;
return MainUI;
})($); })($);
export default MainUI; export default MainUI;