1

我想听鼠标滚轮,如果鼠标位于某个元素上方,请取消默认值并改为执行我的操作。

现在我只想记录事件并阻止它:

  const handleWheel = e => {
    console.log(e);
    e.preventDefault();
  };

使用 svelte 这就是我想出的:

<svelte:window on:wheel={handleWheel} />

不幸的是,这只能让我记录事件,并给出以下错误消息:

无法在被动事件侦听器调用中阻止默认值。

使用纯 JS 的解决方案是添加一个参数:

window.addEventListener("wheel", handleWheel, { passive: false});

但是我在提到如何做到这一点的苗条文档中找不到任何方法。那么,您将如何以苗条的方式做到这一点?

4

2 回答 2

3

好吧,你的代码对我来说确实有效......

<script>
  const handleWheel = e => {
    console.log(e);
    e.preventDefault();
  };
</script>

<svelte:window on:wheel={handleWheel} />

请参阅REPL

也许是你的浏览器,但我想它也可能是 REPL 本身(如果你正在使用的话)可能有一些<svelte:window />事件问​​题,并显示过时的日志......

实际上,您的解决方案会与您想要的相反,并导致警告:

window.addEventListener("wheel", handleWheel, { passive: true });

来自MDN

被动的

一个布尔值,如果为真,则表明侦听器指定的函数将永远不会调用 preventDefault()。如果被动侦听器确实调用了 preventDefault(),用户代理除了生成控制台警告之外什么都不做。

除此之外,Svelte 向事件侦听器添加选项的方法是使用修饰符

例如:

<svelte:window on:wheel|preventDefault={handleWheel} />

<svelte:window on:wheel|passive={handleWheel} />

它们是可组合的,但preventDefault不能passive很好地组合在一起,所以让我们使用另一个:

<svelte:window on:wheel|preventDefault|once={handleWheel} />

有关可用修饰符和详细信息,请参阅 Svelte 的事件文档:

可以使用以下修饰符:

preventDefault — 在运行处理程序之前调用 event.preventDefault()

stopPropagation — 调用 event.stopPropagation(),防止事件到达下一个元素

被动 - 提高触摸/滚轮事件的滚动性能(Svelte 会在安全的地方自动添加它)

capture — 在捕获阶段而不是冒泡阶段触发处理程序

一次——在它第一次运行后移除处理程序

修饰符可以链接在一起,例如on:click|once|capture={...}.

于 2020-02-03T01:54:49.250 回答
3

目前,没有办法用事件处理程序惯用地做到这一点,因为 Chrome通过默认设置某些事件侦听器来破坏网络。有一个开放的 Svelte 问题可以解决这个问题。

同时,最惯用的方式可能是使用一个动作:

<script>
  let scrollable = true;

  const wheel = (node, options) => {
    let { scrollable } = options;

    const handler = e => {
      if (!scrollable) e.preventDefault();
    };

    node.addEventListener('wheel', handler, { passive: false });

    return {
      update(options) {
        scrollable = options.scrollable;
      },
      destroy() {
        node.removeEventListener('wheel', handler, { passive: false });
      }
    };
  };
</script>

<svelte:window use:wheel={{scrollable}} />

演示在这里。

于 2020-02-03T16:46:53.850 回答