You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS下无法阻止`touchmove`事件导致的窗口滚动问题求助

iOS Web App: Blocking Window Scroll While Scrolling a Target Element

Ah, I’ve dealt with this exact headache in Mobile Safari before—let’s break down what’s going on and how to fix it.

The Issue You’re Encountering

You’re trying to implement custom scrolling on a target element while locking the main window from scrolling. Your approach is:

  • Listen to the window's touchmove event
  • Programmatically scroll your target element
  • Call event.preventDefault() to block window scroll

But in Mobile Safari, the window still scrolls underneath your element. This isn’t a mistake in your code—it’s a known WebKit bug.

The bug causes preventDefault() on window-level touchmove events to fail to block main frame scrolling when a child element is being scrolled programmatically, which matches exactly the behavior you’re seeing.

A Reliable Workaround

Instead of fighting WebKit’s default scroll handling, we can explicitly define which elements are allowed to handle touch actions using CSS, then adjust our event listeners to target the right element:

  • Lock the body’s touch behaviors: Add touch-action: none; to your <body> CSS. This tells the browser not to handle default touch actions like scrolling on the main window.
  • Mark your target as the scroll container: Give your scrollable element overflow: auto; (or scroll) and touch-action: pan-y; (use pan-x for horizontal scrolling) to let the browser know it’s the intended scroll target.
  • Move your listener to the target element: Attach the touchmove listener directly to your scrollable element instead of the window. This ensures the browser prioritizes the element’s scroll over the window’s, and lets you handle scroll bounds if needed.

Example Code

Here’s how to implement this:

CSS:

body {
  touch-action: none; /* Disable default window touch scrolling */
  margin: 0;
}

.scrollable-element {
  overflow: auto;
  touch-action: pan-y; /* Allow vertical scrolling on this element */
  height: 80vh; /* Fixed height to enable scrolling */
  padding: 1rem;
  border: 1px solid #eee;
}

JavaScript:

const scrollElement = document.querySelector('.scrollable-element');

scrollElement.addEventListener('touchmove', (e) => {
  // Optional: Check if we've reached the scroll bounds
  const isAtTop = scrollElement.scrollTop === 0;
  const isAtBottom = scrollElement.scrollTop + scrollElement.clientHeight >= scrollElement.scrollHeight;

  // Keep preventDefault if you want to block window scroll even at bounds
  if (!isAtTop && !isAtBottom) {
    e.preventDefault();
  }
});

This approach bypasses the WebKit bug entirely by setting clear scroll priorities upfront, instead of trying to override the window’s behavior after the fact.

内容的提问来源于stack exchange,提问作者Matthew Gertner

火山引擎 最新活动