wheel事件中preventDefault不生效问题及解决方案
问题原因
- 核心原因是
preventDefault被放在了节流判断的逻辑内部:只有满足800ms间隔的滚轮事件才会执行scrollDirection方法,其余被节流丢弃的事件不会触发preventDefault,这些未被拦截的事件就会触发页面默认滚动行为。 - 附加问题:现代浏览器对
wheel、touchmove等滚动类事件默认会开启passive: true优化,此时直接在回调中调用preventDefault会被浏览器忽略,还会在控制台抛出相关警告。
解决方案
方案1:调整节流逻辑,提前拦截默认行为
把阻止默认行为的逻辑移到节流判断外层,保证所有触发的滚轮事件都先禁止默认滚动,再判断是否执行切换逻辑:
<div ref="animated-figure" class="animated-figure-wrapper" > <h1 class="animated-figure__caption">YOU</h1> </div>
mounted() { // 绑定事件时明确指定passive: false,允许阻止默认行为 this.$refs['animated-figure'].addEventListener('wheel', this.throttle(this.scrollDirection, 800), { passive: false }); }, methods: { throttle(func, interval) { let lastCall = 0; return function(e) { // 所有滚轮事件都先阻止默认滚动和冒泡 e.preventDefault(); e.stopImmediatePropagation(); const now = Date.now(); if (lastCall + interval < now) { lastCall = now; return func.apply(this, arguments); } }; }, scrollDirection(e) { e.wheelDeltaY > 0 ? console.log("DOWN") : console.log("UP") } }
方案2:使用Vue事件修饰符(即你提到的已验证可行方案)
直接在模板里绑定事件时用prevent修饰符,Vue会自动处理阻止默认行为,不需要自己在JS里手动调用,还自动适配了passive配置,代码更简洁:
<div ref="animated-figure" class="animated-figure-wrapper" @wheel.prevent="throttle(scrollDirection, 800)" > <h1 class="animated-figure__caption">YOU</h1> </div>
内容的提问来源于stack exchange,提问作者vwjeolzjsebyskrnzf
相关产品推荐
相关产品推荐

