[英]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
event和scroll
event之間存在差異。 wheel
事件在用戶旋轉滾輪按鈕時觸發,而scroll
事件在目標的scrollTop
或scrollLeft
屬性因滾動位置改變而改變時觸發。
當用戶旋轉滾輪按鈕時, wheel
事件會在任何可以觸發的scroll
事件之前觸發。 但是, wheel
事件可能不會導致任何scroll
事件,僅僅是因為指針未懸停在任何元素上或該元素此時不可滾動。
要將快速重復的函數調用聚合到事件處理程序,您可以對事件處理程序函數進行去抖動。 這個想法是在承諾行動之前等待一定的時間。 當一個函數被去抖動時,它就變成了一個新函數,當被調用時,會觸發一個計時器來調用內部的包裝函數。 當再次調用 debounced 函數時,計時器會重置並重新啟動。 請看下面的示例圖。
版權所有 Ilya Kantor( https://javascript.info/ ,現代 JavaScript 教程)
函數f
是一個具有 1000 毫秒超時持續時間的去抖動函數,在時間點 0、200 毫秒和 500 毫秒分別使用參數a
、 b
和c
調用。 因為f
是去抖動的,所以調用f(a)
和f(b)
是“未提交/忽略”的,因為在 1000 毫秒的持續時間內還有對f
的另一個調用。 盡管如此,調用f(c)
在 1500 毫秒的時刻被“提交/接受” ,因為在 1000 毫秒內沒有進一步的調用。
要實現這一點,您可以使用setTimeout
和clearTimeout
函數。 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') }))
您可以設置在將附加滾動事件視為可操作之前必須經過的最短時間。
例如,下面,在再次觸發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.