Trong khi cố gắng giải quyết vấn đề này cho chính mình, tôi nhận thấy rằng thực sự có thể giữ lại cuộn trang và tiêu điểm của đầu vào trong khi vô hiệu hóa các thay đổi số bằng cách cố gắng kích hoạt lại sự kiện đã bắt trên phần tử chính của <input type="number"/>
nó. , đơn giản như thế này:
e.target.parentElement.dispatchEvent(e);
Tuy nhiên, điều này gây ra lỗi trong bảng điều khiển trình duyệt và có lẽ không được đảm bảo hoạt động ở mọi nơi (tôi chỉ thử nghiệm trên Firefox), vì đó là mã cố ý không hợp lệ.
Một giải pháp khác hoạt động tốt ít nhất là trên Firefox và Chromium là tạm thời tạo <input>
phần tử readOnly
, như sau:
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); });
Một tác dụng phụ mà tôi nhận thấy là nó có thể khiến trường nhấp nháy trong tích tắc nếu bạn có kiểu khác nhau cho readOnly
các trường, nhưng ít nhất đối với trường hợp của tôi, điều này dường như không phải là vấn đề.
Tương tự, (như được giải thích trong câu trả lời của James) thay vì sửa đổi readOnly
tính, bạn có thể blur()
điền và sau focus()
đó quay lại trường, nhưng một lần nữa, tùy thuộc vào kiểu được sử dụng, một số hiện tượng nhấp nháy có thể xảy ra.
Ngoài ra, như đã đề cập trong các nhận xét khác ở đây, bạn có thể chỉ cần gọi điện preventDefault()
về sự kiện. Giả sử rằng bạn chỉ xử lý wheel
các sự kiện trên đầu vào số nằm trong tiêu điểm và dưới con trỏ chuột (đó là điều mà ba điều kiện ở trên biểu thị), tác động tiêu cực đến trải nghiệm người dùng sẽ gần như không có.