Pengendalian roda tetikus NumberInput mengabaikan penapisan peristiwa fasa tangkapan
P粉318928159
P粉318928159 2024-04-05 12:21:04
0
1
1551

Versi yang sangat pendek:

Saya agak buntu dan tidak berapa faham kenapa kod ini memang memintas dan menghalang peristiwa roda tetikus daripada ditafsir oleh editor nombor untuk menukar nombor. Saya ingin memahami mengapa peristiwa tangkapan dan penapis pemintasan tidak berfungsi:

Kod 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>

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

Arahan: Klik pada nombor yang dimasukkan untuk memfokuskannya, kemudian gunakan roda tetikus. Roda tetikus dipintas oleh kod JavaScript, tetapi walaupun saya menghentikan penyebaran di sekeliling

semasa fasa tangkapan, nombor masih berubah.

Untuk kemudahan anda: https://jsfiddle.net/Ljku4gha/6/

Apa yang saya ingin capai?

Saya mahu menulis komponen boleh guna semula menggunakan medan input angka lalai (dan peluncur sebenarnya). Saya tidak mahu pengguna boleh menggunakan roda skrol pada input ini untuk menukar nombor. Sebaliknya, roda tetikus harus mencetuskan peristiwa pada beberapa div (tidak diketahui!) (kemungkinan besar) di sekelilingnya untuk tujuan menatal. Jadi saya ingin menghalang editor nombor (dan peluncur) daripada mengendalikan acara roda tetikus dalam beberapa cara.

Versi yang lebih panjang: analisis/hipotesis saya

Saya tidak boleh sepenuhnya menjelaskannya, tetapi terdapat dua hipotesis tentang apa yang berlaku.

Fikiran pertama saya, dan kemungkinan besar, ini adalah artifak cara penyemak imbas mengendalikan acara pengguna (kata kunci "ejen pengguna" saya rasa). Walau bagaimanapun, jika sesiapa boleh menunjukkan tempat saya boleh membaca tentang cara penyemak imbas mengendalikan acara pengguna, itu amat dialu-alukan. Sehingga itu, pemahaman saya tentang pengendalian acara dalam pelayar adalah seperti berikut:

  • Pengguna menatal roda tetikus
  • Giliran JavaScript untuk mengendalikan acara
    • JavaScript melakukan operasi tangkapan/gelembung
    • Pengendali acara boleh menandakan acara sebagai dikendalikan (preventDefault())
  • Di luar JavaScript: Jika pengendali acara dalam JavaScript tidak memanggil PreventDefault(), "ejen pengguna" akan mengambil giliran untuk mengendalikan acara tersebut. Memandangkan tiada kawalan terperinci ke atas perkara ini, langkah ini hanya boleh dihentikan atau diteruskan sepenuhnya. Memandangkan "pengendalian lalai" pengeditan nombor sedang menukar nilai nombor, nombor berubah dan tiada acara tatal dikeluarkan.

Hasil: *sad me*

Namun, saya rasa teori ini paling masuk akal, tetapi mungkin ia salah sama sekali? !

Penjelasan alternatif yang membosankan: Adakah saya mendengar peristiwa yang salah?

Mungkin saya kehilangan sesuatu dan acara roda ditukar kepada acara lain yang boleh saya sekat Default()? Saya tidak dapat mencari sebarang maklumat mengenainya, tetapi ia sangat masuk akal bagi saya... mungkin? Ia bukan "kekili" pun, itu sahaja yang boleh saya katakan.


Saya ingin beberapa panduan untuk membantu saya memahami sebab apa yang saya lakukan tidak berfungsi...dan juga mengalu-alukan penyelesaian!

P粉318928159
P粉318928159

membalas semua(1)
P粉262073176

Gunakan event.preventDefault() untuk menghalang tingkah laku lalai input nombor.

Kami mempunyai 2 penambahbaikan:

  • Halang tatal roda hanya apabila input difokuskan (apabila roda berubah nilai). Dengan cara ini, apabila input tidak fokus, roda skrol akan berkelakuan seperti biasa
  • Apabila input difokuskan, menghalang lalai dan mengaburkan input supaya tatal acara roda seterusnya akan berfungsi semula (anda harus memutuskan sama ada anda mahu pelarasan ini).

Anda tidak boleh membetulkannya dengan menangkap kerana

Malangnya apabila anda menangkap gelagat lalai berlaku sebelum acara menggelembung ke input

Oleh itu stopPropagation() tidak membantu semasa fasa tangkapan.

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

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan