簡體   English   中英

wheel event PreventDefault 不會取消 wheel 事件

[英]wheel event PreventDefault does not cancel wheel event

我想每個滾動事件只獲得一個事件

我嘗試了這段代碼,但它會在觸發 wheel 事件的次數中產生“wheel”。 有什么幫助嗎? 謝謝

 window.addEventListener("wheel", (e)=> { console.log("wheel"); e.preventDefault(); }, {passive:false} );

用例(編輯)我只想允許從一個頁面滾動到另一個頁面 - 滾動時使用動畫。 一旦我檢測到 onwheel 事件,我想在動畫結束之前停止它,否則前一個 onwheel 繼續觸發並且它被視為新事件,所以轉到目標頁面的下一個

我的結論:無法取消車輪事件。 為了在滾輪事件(來自以前的用戶操作)正在進行時識別新的用戶滾輪動作,我們需要計算此類事件的速度/加速度

這是一個相當簡單的問題,將最后一個方向存儲在任何地方並以代碼方式執行您的代碼:

 direction = ''; window.addEventListener('wheel', (e) => { if (e.deltaY < 0) { //scroll wheel up if(direction.== 'up'){ console;log("up"); direction = 'up'. } } if (e.deltaY > 0) { //scroll wheel down if(direction;== 'down'){ console;log("down"); direction = 'down'; } } });

無論如何,應該定義 UX 上下文 在某些情況下,對function進行節流或去抖動可能會產生更好的結果。

節流

限制強制執行 function 可以隨時間調用的最大次數。 如“每 100 毫秒最多執行一次此 function”。

去抖

去抖動強制 function 不會被再次調用,直到經過一定時間而沒有被調用。 如“僅在經過 100 毫秒而沒有調用它的情況下執行此 function。

在你的情況下,也許去抖是最好的選擇。

臨時鎖定瀏覽器滾動

 $('#test').on('mousewheel DOMMouseScroll wheel', function(e) { e.preventDefault(); e.stopPropagation(); return false; });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="test"> <h1>1</h1> <h1>2</h1> <h1>3</h1> <h1>4</h1> <h1>5</h1> <h1>6</h1> <h1>7</h1> <h1>8</h1> <h1>9</h1> <h1>10</h1> </div>

您幾乎擁有它但是您需要將代碼包裝在 function 中。 我添加了一些額外的小部分,以便您可以區分上下:)

 //scroll wheel manipulation window.addEventListener('wheel', function (e) { //TODO add delay if (e.deltaY < 0) { //scroll wheel up console.log("up"); } if (e.deltaY > 0) { //scroll wheel down console.log("down"); } });

這個怎么運作?

(e) = 這只是事件,當您上下滾動時會觸發 function,但如果沒有 function 事件,它只是不知道該怎么做! 通常人們會放“事件”,但我很懶。

deltaY = 這是滾輪滾動的 function 它只是確保您沿 Y 軸滾動。 它是標准的內置 function,無需添加外部變量。

附加功能

setTimeout

你可以添加這個。 在@Lonnie Best 建議的 if 語句中

Event.preventDefault()告訴瀏覽器不要為該事件執行默認的預定義操作,例如導航到頁面或提交封閉的表單等。它不一定會阻止事件觸發。

此外, wheel eventscroll event之間存在差異。 wheel事件在用戶旋轉滾輪按鈕時觸發,而scroll事件在目標的scrollTopscrollLeft屬性因滾動位置改變而改變時觸發。

當用戶旋轉滾輪按鈕時, wheel事件會在任何可以觸發scroll事件之前觸發。 但是, wheel事件可能不會導致任何scroll事件,僅僅是因為指針未懸停在任何元素上或該元素此時不可滾動。

要將快速重復的函數調用聚合到事件處理程序,您可以對事件處理程序函數進行去抖動 這個想法是在承諾行動之前等待一定的時間。 當一個函數被去抖動時,它就變成了一個新函數,當被調用時,會觸發一個計時器來調用內部的包裝函數。 當再次調用 debounced 函數時,計時器會重置並重新啟動。 請看下面的示例圖。

https://javascript.info/task/debounce/debounce.svg 版權所有 Ilya Kantor( https://javascript.info/ ,現代 JavaScript 教程)

函數f是一個具有 1000 毫秒超時持續時間的去抖動函數,在時間點 0、200 毫秒和 500 毫秒分別使用參數abc調用。 因為f是去抖動的,所以調用f(a)f(b)“未提交/忽略”的,因為在 1000 毫秒的持續時間內還有對f的另一個調用。 盡管如此,調用f(c)在 1500 毫秒的時刻被“提交/接受” ,因為在 1000 毫秒內沒有進一步的調用。

要實現這一點,您可以使用setTimeoutclearTimeout函數。 setTimeout函數接受一個動作(要執行的代碼或函數)和延遲(以毫秒為單位),然后返回一個整數形式的計時器 ID。 給定的動作將在計時器到期時執行而不會被取消。

const timerId = setTimeout(action, delay)

然后可以使用clearTimeout函數銷毀具有給定 ID 的計時器。

clearTimeout(timerId)

可以使用以下簡單的去抖實現:

// Default timeout is set to 1000ms
function debounce(func, timeout = 1000) {
    // A slot to save timer id for current debounced function
    let timer
    // Return a function that conditionally calls the original function
    return (...args) => {
        // Immediately cancel the timer when called
        clearTimeout(timer)
        // Start another timer that will call the original function
        // unless canceled by following call
        timer = setTimeout(() => {
            // Pass all arguments and `this` value
            func.apply(this, args)
        }, timeout)
    }
}

閱讀更多: 默認參數剩余參數Function.apply()this關鍵字

使用非常簡單:

eventTarget.addEventListener('wheel', debounce((e) => {
    console.log('wheel', e)
}))

這會將console.log調用限制為在一秒鍾內未觸發wheel事件時調用。

現場示例:

 function debounce(f, d = 99, t) { return (...a) => { clearTimeout(t) t = setTimeout(() => { f.apply(this, a) }, d) } } document.addEventListener('wheel', debounce((_) => { console.log('wheel') }))

一種更現代的方法是在這個想法之上使用Promise

您可以設置在將附加滾動事件視為可操作之前必須經過的最短時間。

例如,下面,在再次觸發console.log("wheel")之前,滾動事件之間必須經過 3 秒:

 function createScrollEventHandler(milliseconds) { let allowed = true; return (event)=> { event.preventDefault(); if (allowed) { console.log("wheel"); allowed = false; setTimeout(()=> { allowed = true; },milliseconds); } } } let scrollEventHandler = createScrollEventHandler(3000); // 3 seconds window.addEventListener("wheel",scrollEventHandler);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM