NumberInput 滑鼠滾輪處理忽略捕捉階段的事件過濾
P粉318928159
P粉318928159 2024-04-05 12:21:04
0
1
1545

非常簡短的版本:

我有點卡住了,不太明白為什麼這段程式碼確實可以攔截和防止滑鼠滾輪事件被數位編輯解釋以更改數字。我想了解為什麼攔截捕獲和過濾事件不起作用:

HTML 程式碼:

<p id="p-number-1">
  <input id="number-1" type="number" min="0" max="100" value="50" class="number-input">
</p>
<p id="log">
</p>

JavaScript 程式碼:

function log(m) {
  const logp = document.getElementById("log")
  logp.innerHTML += "" + m + "<br>";
}

log("Logging started")

const pnum1 = document.getElementById("p-number-1")
const num1 = document.getElementById("number-1")

pnum1.addEventListener("wheel", function(e) { 
    log("captured outer");
    e.stopPropagation();
}, true);

num1.addEventListener("wheel", function(e) { 
    log("bubble inner");
}, false);

num1.addEventListener("wheel", function(e) { 
    log("capture inner");
}, true);

function log(m) {
  const logp = document.getElementById("log")
  logp.innerHTML += "" + m + "<br>";
}

log("Logging started")

const pnum1 = document.getElementById("p-number-1")
const num1 = document.getElementById("number-1")

pnum1.addEventListener("wheel", function(e) { 
    log("captured outer");
    e.stopPropagation();
}, true);

num1.addEventListener("wheel", function(e) { 
    log("bubble inner");
}, false);

num1.addEventListener("wheel", function(e) { 
    log("capture inner");
}, true);

說明:按一下輸入的數字將其聚焦,然後使用滑鼠滾輪。滑鼠滾輪被 JavaScript 程式碼攔截,但即使我在捕獲階段停止了周圍

上的傳播,但仍然會更改數字。

為了您的方便:https://jsfiddle.net/Ljku4gha/6/

我想要達成什麼目標?

我想使用預設的數位輸入欄位(實際上還有滑桿)編寫一個可重複使用的元件。我不希望用戶能夠使用這些輸入上的滾輪來更改數字。相反,滑鼠滾輪應該會觸發周圍某些(未知!)div(最有可能)的事件,以實現滾動目的。所以我想阻止數位編輯(和滑桿)以某種方式處理滑鼠滾輪事件。

較長版本:我的分析/假設

我無法完全解釋它,但對正在發生的事情有兩個假設。

我的第一個想法,也是我認為最有可能的想法是,這是瀏覽器如何處理使用者事件的產物(我認為關鍵字「使用者代理」)。然而,如果有人能指出在哪裡可以閱讀瀏覽器如何處理用戶事件,那將非常受歡迎。在那之前,我對瀏覽器中事件處理的理解如下:

  • 使用者滾動滑鼠滾輪
  • 輪到 JavaScript 處理事件
    • JavaScript 執行擷取/冒泡操作
    • 事件處理程序可以將事件標記為已處理 (preventDefault())
  • JavaScript 之外:如果 JavaScript 中的事件處理程序未呼叫 PreventDefault(),則「使用者代理程式」將輪到處理該事件。由於對此沒有細粒度的控制,因此這一步只能完全停止或繼續。由於數位編輯的「預設處理」正在更改數字值,因此數字會更改並且不會發出滾動事件。

結果:*sad me*

但是,我認為這個理論最有道理,但也許它是完全錯誤的? !

另類無聊的解釋:我監聽了錯誤的事件?

也許我遺漏了一些東西,而輪子事件被轉換為我可以阻止Default()的其他事件?我找不到任何相關信息,但這對我來說非常有意義......也許?這甚至不是一個“捲軸”,我只能說這麼多。


我主要想得到一些指導,幫助我理解為什麼我所做的事情不起作用......並且也歡迎解決方案!

P粉318928159
P粉318928159

全部回覆(1)
P粉262073176

使用 event.preventDefault() 阻止數字輸入的預設行為。

我們有 2 項改進:

  • 僅在輸入聚焦時(當滾輪變更值時)防止滾輪。這樣,當輸入未聚焦時,滾輪會像平常一樣運行
  • 當輸入聚焦時,會阻止預設情況並模糊輸入,以便下一個滾輪事件滾動將再次起作用(您應該決定是否需要此調整)。

您無法透過捕獲來解決這個問題,因為

不幸的是,當您捕獲預設行為發生在事件冒泡到輸入之前時

因此 stopPropagation() 在捕獲階段沒有幫助。

const p = document.getElementById("p-number-1")
const num1 = document.getElementById("number-1")



num1.addEventListener("wheel", function(e) { 
    console.log("input wheel");
    if(e.target.matches(':focus')){
      console.log("input wheel prevented");
      e.preventDefault();
      e.target.blur();
    }
}, false);
p{
  height:1000px;
}
input{
  pointer-events: none1;
}

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板