ในขณะที่พยายามแก้ปัญหานี้ด้วยตัวเองฉันสังเกตเห็นว่าเป็นไปได้จริงที่จะคงการเลื่อนของหน้าและโฟกัสของข้อมูลเข้าในขณะที่ปิดใช้งานการเปลี่ยนแปลงตัวเลขโดยพยายามที่จะเริ่มเหตุการณ์ที่จับได้อีกครั้งในองค์ประกอบหลักของ<input type="number"/>
ที่จับได้ เพียงแค่นี้:
e.target.parentElement.dispatchEvent(e);
อย่างไรก็ตามสิ่งนี้ทำให้เกิดข้อผิดพลาดในคอนโซลของเบราว์เซอร์และอาจไม่รับประกันว่าจะทำงานได้ทุกที่ (ฉันทดสอบบน Firefox เท่านั้น) เนื่องจากเป็นรหัสที่ไม่ถูกต้องโดยเจตนา
อีกวิธีหนึ่งที่ทำงานได้ดีอย่างน้อยบน Firefox และ Chromium คือการสร้าง<input>
องค์ประกอบชั่วคราวreadOnly
เช่นนี้:
function handleScroll(e) {
if (e.target.tagName.toLowerCase() === 'input'
&& (e.target.type === 'number')
&& (e.target === document.activeElement)
&& !e.target.readOnly
) {
e.target.readOnly = true;
setTimeout(function(el){ el.readOnly = false; }, 0, e.target);
}
}
document.addEventListener('wheel', function(e){ handleScroll(e); });
ผลข้างเคียงอย่างหนึ่งที่ฉันสังเกตเห็นคือมันอาจทำให้สนามสั่นไหวในเสี้ยววินาทีหากคุณมีสไตล์ที่แตกต่างกันสำหรับreadOnly
ฟิลด์ แต่สำหรับกรณีของฉันอย่างน้อยก็ดูเหมือนจะไม่เป็นปัญหา
ในทำนองเดียวกัน (ตามที่อธิบายไว้ในคำตอบของเจมส์) แทนที่จะแก้ไขreadOnly
คุณสมบัติคุณสามารถblur()
ฟิลด์แล้วfocus()
ย้อนกลับ แต่อีกครั้งขึ้นอยู่กับรูปแบบที่ใช้อาจเกิดการกะพริบ
หรือตามที่กล่าวไว้ในความคิดเห็นอื่น ๆ ที่นี่คุณสามารถโทรpreventDefault()
เข้าร่วมกิจกรรมแทนได้ สมมติว่าคุณจัดการเฉพาะwheel
เหตุการณ์เกี่ยวกับอินพุตตัวเลขที่อยู่ในโฟกัสและอยู่ใต้เคอร์เซอร์ของเมาส์ (นั่นคือสิ่งที่สามเงื่อนไขข้างต้นหมายถึง) ผลกระทบเชิงลบต่อประสบการณ์ของผู้ใช้จะแทบไม่มีเลย