You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:09:28