使用Isotope2与Scroll-js实现点击元素滚动的异常问题排查
解决Isotope扩展后Scroll-js滚动起始位置异常问题
我之前也碰到过类似的情况——用Isotope做Masonry布局,点击元素扩展后用Scroll-js滚动,结果滚动不是从当前页面位置开始,而是直接从页面顶部触发。结合你的代码来看,问题主要出在变量引用的小问题和Isotope布局完成后的元素位置同步上,咱们一步步来修复:
首先,先看你的代码里几个需要调整的点:
1. 修复全局变量污染问题
在Helpers.clickedGridItem里,你不小心用了一个未声明的全局clickedItem变量,这可能导致后续引用出错。改成纯返回找到的元素即可:
clickedGridItem: function(eve) { return eve.path.find(el => el.classList.contains('grid-item')); }
2. 确保Isotope布局完全稳定后再滚动
Isotope的layoutComplete事件虽然会在布局完成后触发,但有时候浏览器的重排可能有微小的滞后,直接调用滚动可能会拿到旧的元素位置。给滚动加个50ms的微小延迟,确保元素位置已经更新:
scroll: function() { if (!Services.clickedGridItem) return; setTimeout(() => { Services.scroll.toElement(Services.clickedGridItem, { duration: 1000, offset: 0, // 确保元素顶部对齐视口顶部 easing: 'easeInOutQuad' // 可选,让滚动更平滑 }); }, 50); }
3. 优化点击事件的逻辑
在点击事件里加上e.preventDefault()避免不必要的默认行为,同时确保clickedGridItem的赋值清晰:
toggleExpand: function(e) { e.preventDefault(); const clickedGridItem = Services.clickedGridItem = Services.Helpers.clickedGridItem(e); clickedGridItem.classList.toggle('grid-item--width2'); Services.iso.layout(); }
完整修改后的代码
window._ = (...myvar) => console.log(...myvar); const Services = { /** * default values for Isotope * @type {Object} */ gridDefaults: { itemSelector: '.grid-item', percentPositions: true, masonry: { gutter: '.gutter-sizer', columnWidth: '.grid-sizer' } }, clickedGridItem: null, /** * Initializes the module * @return {undefined} Executive method used to plug the module in. */ init: () => { _('Services module initialized'); Services.scroll = new Scroll(document.body); const grid = document.querySelector('.grid'); const gridItems = grid.querySelectorAll('.grid-item'); gridItems.forEach(gridItem => { gridItem.addEventListener('click', Services.Listeners.toggleExpand); }); // Initialize Isotope const iso = Services.iso = new Isotope(grid, Services.gridDefaults); iso.on('layoutComplete', Services.Listeners.scroll); }, Listeners: { toggleExpand: function(e) { e.preventDefault(); const clickedGridItem = Services.clickedGridItem = Services.Helpers.clickedGridItem(e); clickedGridItem.classList.toggle('grid-item--width2'); Services.iso.layout(); }, scroll: function() { if (!Services.clickedGridItem) return; // Add a tiny delay to ensure Isotope has finished updating positions setTimeout(() => { Services.scroll.toElement(Services.clickedGridItem, { duration: 1000, offset: 0, easing: 'easeInOutQuad' }); }, 50); } }, Helpers: { clickedGridItem: function(eve) { return eve.path.find(el => el.classList.contains('grid-item')); } } }; Services.init();
这样调整后,滚动就会从当前页面的位置开始,平滑滚动到扩展后的网格项顶部了——核心就是确保元素位置完全更新后再触发滚动,同时避免变量引用的问题。
内容的提问来源于stack exchange,提问作者crs1138
相关产品推荐
相关产品推荐

