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

Chart.js Zoom插件:默认滚动失效,需区分XY轴滚动行为

解决Chart.js Zoom插件与页面Y轴滚动冲突问题

我用Chart.js实现了一款柱状图,支持用户滚动查看近两年的月度数据,为此引入Chart.js Zoom插件实现X轴平移功能。但插件会自动给canvas添加touch-action: none样式,导致页面Y轴滚动失效。将该属性改为auto虽恢复了Y轴滚动,却破坏了柱状图的X轴平移功能。现需实现精准区分用户操作:横向拖动时触发X轴平移展示往期数据,纵向滚动时保留页面默认滚动行为。


插件自动添加的Canvas样式

display: block;
box-sizing: border-box;
height: 300px;
width: 343px;
touch-action: none;
user-select: none;
-webkit-user-drag: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);

当前Chart.js配置(TS)

plugins: {
  zoom: {
    pan: {
      sensitivity: 6,
      enabled: true,
      mode: 'x',
      speed: 0.2,
      threshold: 8,
    },
  },
}

可行解决方案

1. 动态控制touch-action属性

通过监听canvas的触摸事件,根据用户初始拖动方向动态修改touch-action属性:

  • 触摸开始时记录初始触摸坐标
  • 触摸移动时计算X、Y方向的偏移量,判断用户主要操作方向
  • 横向拖动时设置touch-action: pan-x,触发插件的X轴平移;纵向滚动时设置touch-action: pan-y,保留页面滚动
  • 触摸结束后重置属性,确保后续操作正常触发

示例代码:

const chartCanvas = document.getElementById('your-chart-canvas') as HTMLCanvasElement;
let startX = 0;
let startY = 0;

chartCanvas.addEventListener('touchstart', (e) => {
  startX = e.touches[0].clientX;
  startY = e.touches[0].clientY;
});

chartCanvas.addEventListener('touchmove', (e) => {
  const deltaX = Math.abs(e.touches[0].clientX - startX);
  const deltaY = Math.abs(e.touches[0].clientY - startY);
  
  if (deltaX > deltaY) {
    chartCanvas.style.touchAction = 'pan-x';
  } else {
    chartCanvas.style.touchAction = 'pan-y';
  }
}, { passive: false });

chartCanvas.addEventListener('touchend', () => {
  chartCanvas.style.touchAction = 'none';
});

2. 调整Zoom插件阈值+修改touch-action

直接设置canvas的touch-action: pan-x pan-y,同时增大插件的threshold值,减少纵向滚动时误触发X轴平移的概率:

  • 修改CSS覆盖默认样式:
#your-chart-canvas {
  touch-action: pan-x pan-y !important;
}
  • 更新Chart.js配置:
plugins: {
  zoom: {
    pan: {
      sensitivity: 6,
      enabled: true,
      mode: 'x',
      speed: 0.2,
      threshold: 20, // 增大阈值,仅当横向偏移超过20px时触发平移
    },
  },
}

3. 自定义Zoom插件触摸逻辑

重写Zoom插件的触摸处理方法,在touchmove事件中判断操作方向:

  • 若检测到纵向滚动,不阻止默认事件,让页面正常滚动;若为横向拖动,继续执行插件的平移逻辑
  • 此方法需要对Zoom插件源码有一定了解,适合需要高度定制的场景

内容的提问来源于stack exchange,提问作者Sudharsan S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 02:33:38