Files
kupshop/admin/static/js/wpj.domUtils.js
2025-08-02 16:30:27 +02:00

206 lines
6.1 KiB
JavaScript

wpj.domUtils = {
crossFade: function ($old, $new, complete)
{
var width,
height = $old.outerHeight(true),
speed = 300;
if ($old[0].getBoundingClientRect().width)
width = $old[0].getBoundingClientRect().width;
else
width = $old.outerWidth(true);
if (width <= 0)
{
$old.before($new).hide();
if (complete)
complete($old, $new);
else
$old.remove();
return;
}
var $positionWrap = $old.wrap($('<div class="crossfade-wrapper">').width(width).height(height)).parent(),
$oldWrap = $old.wrap('<div class="crossfade-position old">').parent(),
$newWrap = $new.wrap('<div class="crossfade-position new">').parent();
$newWrap.css({opacity: 0});
$positionWrap.append($newWrap);
$new.trigger('crossFaded');
$oldWrap.animate({opacity: 0}, speed);
$newWrap.animate({opacity: 1}, speed, undefined, function()
{
$oldWrap.unwrap();
$old.unwrap();
$new.unwrap();
if (complete)
complete($old, $new);
else
$old.remove();
});
var new_height = $newWrap.height(),
old_height = $positionWrap.height();
if (old_height != new_height)
$positionWrap.animate({height: new_height}, speed);
},
reloadParts: function($selector, dataPromise, finishedCallback)
{
// Set all parts to loading state
$selector.addClass('reload-loading').animate({opacity: 0.66}, 300);
dataPromise.done(function($html){
var newParts = wpj.domUtils.crossFadeParts($selector, $html);
$selector.removeClass('reload-loading');
if (finishedCallback)
finishedCallback(newParts);
});
},
crossFadeParts: function($oldParts, $newHtml)
{
var $oldPart, $newPart, newParts = [], selector;
$oldParts.each(function(){
$oldPart = $(this);
selector = '[data-reload="'+$oldPart.data('reload')+'"]';
$newPart = $newHtml.find(selector).addBack(selector);
$.merge(newParts, $newPart);
if ($oldPart.closest('.crossfade-wrapper').length || !document.documentElement.contains(this))
{
// console.log('$old', 'in crossfade', $oldPart.closest('.crossfade-wrapper').length, 'removed', !document.documentElement.contains(this));
$oldPart = $('[data-reload="'+$oldPart.data('reload')+'"]');
if ($oldPart.length > 1)
$oldPart = $oldPart.filter('.crossfade-position.new > [data-reload]');
$oldPart.html($newPart.html());
return;
}
if (!$newPart.length)
{
// Create dummy empty element if element not in result
$newPart = $('<div>').attr('data-reload', $oldPart.data('reload'));
}
wpj.domUtils.crossFade($oldPart, $newPart);
});
return newParts;
},
reloadPartsFromUrl: function(url, $oldParts, data)
{
// Load new category products
var dataLoaded = $.Deferred(),
method = data ? 'post' : 'get';
wpj.domUtils.reloadParts($oldParts, dataLoaded);
$[method](url, data, function (data) {
dataLoaded.resolve(wpj.domUtils.parseHtml(data));
});
},
getHash: function()
{
return location.href.split("#")[1] || "";
},
parseHtml: function (html, selector)
{
var $content = $("<div>").append($.parseHTML(html, true));
if (selector)
return $content.find(selector);
else
return $content.children();
},
scrollTo: function ($anchor, speed)
{
var offset = $anchor.offset();
if (speed == undefined)
speed = 1000;
if (offset)
{
$('html, body').stop().animate({
scrollTop: offset.top - 100
}, speed);
}
},
activeTimers: {},
resetTimer: function (id, timeout, callback)
{
var timers = wpj.domUtils.activeTimers,
timer = timers[id];
if (timer)
clearTimeout(timer);
timers[id] = setTimeout(function ()
{
delete timers[id];
callback();
}, timeout);
},
initOpeners: function($selector)
{
if (!$selector)
$selector = $('body');
// Disable animation during init to avoid reflows
$.fx.off = true;
var event = 'change';
if (!$selector.is('input'))
event = 'click';
$selector.on(event + ' update', '[data-opener]', function(e){
var $this = $(e.currentTarget),
$target = $($this.data('opener')),
checked;
if ($this.is('input'))
checked = $this.is(':checked');
else
{
checked = $this.is('.active');
if (e.type != 'update')
checked = !checked;
}
$target[checked ? 'slideDown' : 'slideUp']()[checked ? 'addClass' : 'removeClass']('active').trigger('opened');
$this[checked ? 'addClass' : 'removeClass']('active');
return !$this.is('a');
})
// Trigger change event on init to update target visibility
.find('[data-opener]').trigger('update');
$.fx.off = false;
},
isInView: function ($elem)
{
var $window = $(window),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
},
/**
* @param {HTMLElement} openerHtmlElement
*/
expandOpener: function (openerHtmlElement)
{
var $opener = $(openerHtmlElement);
$opener.addClass('active');
$opener.trigger('update');
}
};