如何在 svelte 中向 window 事件/鼠标滚轮添加参数
How to add parameters to a window event / mouse wheel in svelte
我想听鼠标滚轮的声音,如果鼠标位于某个元素上方,则取消默认设置并改为执行我的操作。
现在我只想记录事件并阻止它:
const handleWheel = e => {
console.log(e);
e.preventDefault();
};
使用 svelte 这就是我想到的:
<svelte:window on:wheel={handleWheel} />
不幸的是,这只会让我记录事件,并给出此错误消息:
Unable to preventDefault inside passive event listener invocation.
使用纯JS解决办法是加一个参数:
window.addEventListener("wheel", handleWheel, { passive: false});
但我在提及如何完成此操作的 svelte 文档中找不到任何方法。那么你将如何以苗条的方式做到这一点?
好吧,你的代码对我来说确实有效...
<script>
const handleWheel = e => {
console.log(e);
e.preventDefault();
};
</script>
<svelte:window on:wheel={handleWheel} />
参见 in the REPL。
可能是您的浏览器问题,但我想也可能是 REPL 本身(如果您使用的是它)<svelte:window />
事件可能存在一些问题,并显示过时的日志...
实际上,您的解决方案会做与您想要的相反的事情,并导致警告:
window.addEventListener("wheel", handleWheel, { passive: true });
来自 MDN:
passive
A Boolean which, if true, indicates that the function specified by listener will never call preventDefault(). If a passive listener does call preventDefault(), the user agent will do nothing other than generate a console warning.
除此之外,Svelte 向事件侦听器添加选项的方法是使用 修饰符。
例如:
<svelte:window on:wheel|preventDefault={handleWheel} />
<svelte:window on:wheel|passive={handleWheel} />
它们可以组合,但是 preventDefault
和 passive
不能很好地组合在一起,所以让我们使用另一个:
<svelte:window on:wheel|preventDefault|once={handleWheel} />
有关可用修饰符和详细信息,请参阅 Svelte 的 docs on events:
The following modifiers are available:
preventDefault — calls event.preventDefault() before running the handler
stopPropagation — calls event.stopPropagation(), preventing the event reaching the next element
passive — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
capture — fires the handler during the capture phase instead of the bubbling phase
once — remove the handler after the first time it runs
Modifiers can be chained together, e.g. on:click|once|capture={...}
.
目前,无法使用事件处理程序以惯用的方式执行此操作,因为 Chrome broke the web by making certain event listeners passive by default. There's an open Svelte issue 可以解决此问题。
同时,最惯用的方法可能是使用一个动作:
<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}} />
我想听鼠标滚轮的声音,如果鼠标位于某个元素上方,则取消默认设置并改为执行我的操作。
现在我只想记录事件并阻止它:
const handleWheel = e => {
console.log(e);
e.preventDefault();
};
使用 svelte 这就是我想到的:
<svelte:window on:wheel={handleWheel} />
不幸的是,这只会让我记录事件,并给出此错误消息:
Unable to preventDefault inside passive event listener invocation.
使用纯JS解决办法是加一个参数:
window.addEventListener("wheel", handleWheel, { passive: false});
但我在提及如何完成此操作的 svelte 文档中找不到任何方法。那么你将如何以苗条的方式做到这一点?
好吧,你的代码对我来说确实有效...
<script>
const handleWheel = e => {
console.log(e);
e.preventDefault();
};
</script>
<svelte:window on:wheel={handleWheel} />
参见 in the REPL。
可能是您的浏览器问题,但我想也可能是 REPL 本身(如果您使用的是它)<svelte:window />
事件可能存在一些问题,并显示过时的日志...
实际上,您的解决方案会做与您想要的相反的事情,并导致警告:
window.addEventListener("wheel", handleWheel, { passive: true });
来自 MDN:
passive
A Boolean which, if true, indicates that the function specified by listener will never call preventDefault(). If a passive listener does call preventDefault(), the user agent will do nothing other than generate a console warning.
除此之外,Svelte 向事件侦听器添加选项的方法是使用 修饰符。
例如:
<svelte:window on:wheel|preventDefault={handleWheel} />
<svelte:window on:wheel|passive={handleWheel} />
它们可以组合,但是 preventDefault
和 passive
不能很好地组合在一起,所以让我们使用另一个:
<svelte:window on:wheel|preventDefault|once={handleWheel} />
有关可用修饰符和详细信息,请参阅 Svelte 的 docs on events:
The following modifiers are available:
preventDefault — calls event.preventDefault() before running the handler
stopPropagation — calls event.stopPropagation(), preventing the event reaching the next element
passive — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
capture — fires the handler during the capture phase instead of the bubbling phase
once — remove the handler after the first time it runs
Modifiers can be chained together, e.g.
on:click|once|capture={...}
.
目前,无法使用事件处理程序以惯用的方式执行此操作,因为 Chrome broke the web by making certain event listeners passive by default. There's an open Svelte issue 可以解决此问题。
同时,最惯用的方法可能是使用一个动作:
<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}} />