function debounce(func, wait, immediate) { let timeout; return function () { let context = this; let args = arguments; let later = function () { timeout = null; if (!immediate) { func.apply(context, args); } }; let callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) { func.apply(context, args); } }; } function observeResize(masonry) { let resizeObserver = new ResizeObserver(debounce(function () { masonry.layout(); }, 100)); let items = document.querySelectorAll('.isekai-masonry-item'); items.forEach(function (item) { resizeObserver.observe(item); }); } function observeResizeFallback(masonry) { console.log('ResizeObserver not supported, using fallback'); let itemHeights = []; let items = document.querySelectorAll('.isekai-masonry-item'); items.forEach(function (item) { itemHeights.push(item.clientHeight); }); setInterval(function () { let isResized = false; items.forEach(function (item, index) { if (item.clientHeight !== itemHeights[index]) { isResized = true; itemHeights[index] = item.clientHeight; } }); if (isResized) { masonry.layout(); } }, 1000); } $(function () { let masonry = new isekai.lib.Masonry('.isekai-masonry', { itemSelector: '.isekai-masonry-item', columnWidth: '.isekai-masonry-sizer', gutter: '.isekai-masonry-gutter-sizer', percentPosition: true }); if (typeof ResizeObserver !== 'undefined') { observeResize(masonry); } else { observeResizeFallback(masonry); } });