Die Handhabung des NumberInput-Mausrads ignoriert die Filterung von Erfassungsphasenereignissen
P粉318928159
P粉318928159 2024-04-05 12:21:04
0
1
1548

Sehr kurze Version:

Ich stecke etwas fest und verstehe nicht ganz, warum dieser Code tatsächlich Mausradereignisse abfängt und verhindert, dass sie vom Zahleneditor zum Ändern von Zahlen interpretiert werden. Ich möchte verstehen, warum Abfangerfassung und Filterereignisse nicht funktionieren:

HTML-Code:

<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-Code:

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);

Anleitung: Klicken Sie auf die eingegebene Zahl, um sie zu fokussieren, und verwenden Sie dann das Mausrad. Das Mausrad wird vom JavaScript-Code abgefangen, aber selbst wenn ich die Ausbreitung auf die Umgebung

während der Erfassungsphase stoppe, ändern sich die Zahlen immer noch.

Für Ihre Bequemlichkeit: https://jsfiddle.net/Ljku4gha/6/

Was möchte ich erreichen?

Ich möchte eine wiederverwendbare Komponente unter Verwendung des standardmäßigen numerischen Eingabefelds (und eigentlich des Schiebereglers) schreiben. Ich möchte nicht, dass der Benutzer bei diesen Eingaben das Scrollrad verwenden kann, um die Zahlen zu ändern. Stattdessen sollte das Mausrad zum Scrollen Ereignisse auf einem (unbekannten!) Div (höchstwahrscheinlich) in der Umgebung auslösen. Deshalb möchte ich verhindern, dass der Zahleneditor (und der Schieberegler) Mausradereignisse auf irgendeine Weise verarbeiten.

Längere Version: meine Analyse/Hypothesen

Ich kann es nicht vollständig erklären, aber es gibt zwei Hypothesen darüber, was vor sich geht.

Mein erster Gedanke, und was ich für den wahrscheinlichsten halte, ist, dass dies ein Artefakt der Art und Weise ist, wie Browser mit Benutzerereignissen umgehen (Stichwort „Benutzeragent“, glaube ich). Wenn mir jedoch jemand sagen könnte, wo ich nachlesen kann, wie Browser mit Benutzerereignissen umgehen, wäre ich sehr willkommen. Bis dahin ist mein Verständnis der Ereignisbehandlung in Browsern wie folgt:

  • Benutzer scrollt mit dem Mausrad
  • JavaScript ist an der Reihe, das Ereignis zu verarbeiten
    • JavaScript führt den Erfassungs-/Blasenvorgang aus
    • Ereignishandler können Ereignisse als behandelt markieren (preventDefault())
  • Außerhalb von JavaScript: Wenn der Ereignishandler in JavaScript PreventDefault() nicht aufruft, ist der „Benutzeragent“ an der Reihe, das Ereignis zu verarbeiten. Da hierüber keine feingranulare Kontrolle besteht, kann dieser Schritt nur komplett gestoppt bzw. fortgesetzt werden. Da die „Standardbehandlung“ der Zahlenbearbeitung darin besteht, den Zahlenwert zu ändern, ändert sich die Zahl und es wird kein Scroll-Ereignis ausgegeben.

Ergebnis: *sad me*

Ich denke jedoch, dass diese Theorie am sinnvollsten ist, aber vielleicht ist sie völlig falsch? !

Alternative langweilige Erklärung: Höre ich die falsche Veranstaltung?

Vielleicht übersehe ich etwas und die Radereignisse werden in andere Ereignisse umgewandelt, für die ich Default() blockieren kann? Ich kann keine Informationen darüber finden, aber es macht für mich vollkommen Sinn ... vielleicht? Es ist nicht einmal eine „Rolle“, das ist alles, was ich sagen kann.


Ich hätte vor allem gerne eine Anleitung, die mir hilft zu verstehen, warum das, was ich tue, nicht funktioniert ... und würde mich auch über Lösungen freuen!

P粉318928159
P粉318928159

Antworte allen(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;
}

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage