입력 번호 필드의 번호를 변경하는 스크롤 휠을 비활성화 할 수 있습니까? 스피너를 제거하기 위해 웹킷 관련 CSS를 엉망으로 만들었지 만이 동작을 모두 제거하고 싶습니다. type=numberiOS에서 멋진 키보드가 나오기 때문에 사용 하는 것이 좋습니다.
onscroll핸들러 를 추가하면 event.preventDefault()어떻게 되나요?
입력 번호 필드의 번호를 변경하는 스크롤 휠을 비활성화 할 수 있습니까? 스피너를 제거하기 위해 웹킷 관련 CSS를 엉망으로 만들었지 만이 동작을 모두 제거하고 싶습니다. type=numberiOS에서 멋진 키보드가 나오기 때문에 사용 하는 것이 좋습니다.
onscroll핸들러 를 추가하면 event.preventDefault()어떻게 되나요?
답변:
다른 사람들이 제안한 것과 같이 입력 번호 요소에서 마우스 휠 이벤트의 기본 동작을 방지합니다 ( "blur ()"호출은 일반적으로 사용자가 원하는 것이 아니기 때문에 선호하는 방법이 아닙니다).
그러나. 항상 모든 input-number 요소에서 mousewheel 이벤트를 수신하지 않고 요소에 초점이 맞춰져있을 때만 수행합니다 (문제가 존재하는 경우). 그렇지 않으면 마우스 포인터가 input-number 요소 위에있을 때 사용자가 페이지를 스크롤 할 수 없습니다 .
jQuery 솔루션 :
// disable mousewheel on a input number field when in focus
// (to prevent Cromium browsers change the value when scrolling)
$('form').on('focus', 'input[type=number]', function (e) {
$(this).on('wheel.disableScroll', function (e) {
e.preventDefault()
})
})
$('form').on('blur', 'input[type=number]', function (e) {
$(this).off('wheel.disableScroll')
})
(포커스 이벤트를 주변 양식 요소로 위임-성능에 좋지 않은 많은 이벤트 리스너를 피하십시오.)
$(document).on("wheel", "input[type=number]", function (e) {
$(this).blur();
});
이것은 순수한 js에서 @Simon Perepelitsa 의 대답 과 비슷 하지만 문서 요소에 하나의 이벤트 리스너를 놓고 포커스가있는 요소가 숫자 입력인지 확인하므로 조금 더 간단합니다.
document.addEventListener("wheel", function(event){
if(document.activeElement.type === "number"){
document.activeElement.blur();
}
});
일부 필드 에서 값 스크롤 동작을 끄고 싶지만 다른 필드에서는 끄려면 대신 다음을 수행하십시오.
document.addEventListener("wheel", function(event){
if(document.activeElement.type === "number" &&
document.activeElement.classList.contains("noscroll"))
{
document.activeElement.blur();
}
});
이것으로 :
<input type="number" class="noscroll"/>
입력에 noscroll 클래스가 있으면 스크롤시 변경되지 않으며 그렇지 않으면 모든 것이 동일하게 유지됩니다.
wheel대신 이벤트를 사용하십시오 mousewheel. 참조 : developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event PS. 나는 반대표를 던진 사람이 아닙니다.
input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(event){ this.blur() })
jQuery 예제 및 크로스 브라우저 솔루션은 관련 질문을 참조하십시오.
$(':input[type=number]' ).live('mousewheel',function(e){ $(this).blur(); });나는 기본 방지 대신 흐림을 사용하여 페이지 스크롤을 차단하지 않는다!
live()더 이상 사용되지 않습니다. 이제 다음을 사용해야합니다 on(). $(':input[type=number]').on('mousewheel',function(e){ $(this).blur(); });
wheel대신 이벤트를 사용하십시오 mousewheel. 참조 : developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event
HTML onwheel 속성을 사용하기 만하면됩니다 .
이 옵션은 페이지의 다른 요소를 스크롤하는 데 영향을주지 않습니다.
그리고 모든 입력에 대한 리스너를 추가하면 사후에 동적으로 생성 된 입력에서 작동하지 않습니다.
Aditionaly, CSS를 사용하여 입력 화살표를 제거 할 수 있습니다.
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
<input type="number" onwheel="this.blur()" />
onBlur()예상과 다릅니다. 나는 return false정말로 "아무것도하지 않는"대신 간단한 것을 설정했다 . <input type="number" onwheel="return false;">
@Semyon Perepelitsa
이것에 대한 더 나은 해결책이 있습니다. 블러 는 입력에서 초점을 제거하고 원하지 않는 부수적 인 영향입니다. 대신 evt.preventDefault를 사용해야합니다. 이것은 사용자가 스크롤 할 때 입력의 기본 동작을 방지합니다. 다음은 코드입니다.
input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(evt){ evt.preventDefault(); })
wheel대신 이벤트를 사용하십시오 mousewheel. 참조 : developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event
먼저 다음 중 하나를 수행하여 마우스 휠 이벤트를 중지해야합니다.
mousewheel.disableScrolle.preventDefault();el.blur();처음 두 가지 방법은 창 스크롤을 중지하고 마지막 두 가지 방법은 요소에서 포커스를 제거합니다. 둘 다 바람직하지 않은 결과입니다.
한 가지 해결 방법은 el.blur()지연 후 요소 를 사용 하고 다시 초점을 맞추는 것입니다.
$('input[type=number]').on('mousewheel', function(){
var el = $(this);
el.blur();
setTimeout(function(){
el.focus();
}, 10);
});
var hadFocus = el.is(':focus');블러 링 전, 그리고 hadFocs가 참인 경우에만 타임 아웃을 설정하는 가드.
React로 작업하고 솔루션을 찾는 모든 사람을 위해. 가장 쉬운 방법은 다음과 같이 입력 구성 요소에서 onWheelCapture prop을 사용하는 것입니다.
onWheelCapture={e => {
e.target.blur()
}}
Typescript는 형식 안전성을 위해 HTMLElement로 작업하고 있음을 알아야합니다. 그렇지 않으면 많은 Property 'type' does not exist on type 'Element'유형의 오류가 표시됩니다.
document.addEventListener("mousewheel", function(event){
let numberInput = (<HTMLInputElement>document.activeElement);
if (numberInput.type === "number") {
numberInput.blur();
}
});
이 문제를 직접 해결하려고 시도하는 동안 실제로 페이지 스크롤을 유지하고 입력의 초점을 유지하면서 숫자 변경을 비활성화하는 것이 포착 된의 부모 요소에서 포착 된 이벤트를 다시 실행하려고 시도함으로써 가능하다는 것을 알았 <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. 그러나 제 경우에는 적어도 이것은 문제가되지 않는 것 같습니다.
마찬가지로 (James의 답변에서 설명했듯이) readOnly속성 을 수정하는 대신 blur()필드를 한 다음 focus()다시 되돌릴 수 있지만 사용하는 스타일에 따라 약간의 깜박임이 발생할 수 있습니다.
또는 여기의 다른 의견에서 언급했듯이 preventDefault()대신 이벤트를 호출 할 수 있습니다 . wheel포커스가 있고 마우스 커서 아래에있는 숫자 입력에 대해서만 이벤트를 처리한다고 가정하면 (위의 세 가지 조건이 의미하는 것입니다) 사용자 경험에 대한 부정적인 영향은 거의 없을 것입니다.
JavaScript가 필요하지 않은 솔루션을 원한다면 일부 HTML 기능을 CSS 의사 요소와 결합하면 트릭이됩니다.
span {
position: relative;
display: inline-block; /* Fit around contents */
}
span::after {
content: "";
position: absolute;
top: 0; right: 0; bottom: 0; left: 0; /* Stretch over containing block */
cursor: text; /* restore I-beam cursor */
}
/* Restore context menu while editing */
input:focus {
position: relative;
z-index: 1;
}
<label>How many javascripts can u fit in u mouth?
<span><input type="number" min="0" max="99" value="1"></span>
</label>
이는 <label>양식 필드와 연결된 의 내용을 클릭하면 필드에 초점이 맞춰 지기 때문에 작동 합니다. 그러나 필드 위에있는 의사 요소의 "창"은 마우스 휠 이벤트가 도달하는 것을 차단합니다.
단점은 위로 / 아래로 스피너 버튼이 더 이상 작동하지 않지만 어쨌든 제거했다고 말했습니다.
이론적으로는 입력에 먼저 초점을 두지 않고도 컨텍스트 메뉴를 복원 할 수 있습니다. 브라우저는 성능상의 이유로 스크롤 중에 :hover스타일 을 다시 계산하지 않기 때문에 사용자가 스크롤 할 때 스타일 이 실행되지 않아야 하지만 브라우저 / 장치를 완전히 교차하지는 않았습니다. 그것을 테스트했습니다.
function fixNumericScrolling() {
$$( "input[type=number]" ).addEvent( "mousewheel", function(e) {
stopAll(e);
} );
}
function stopAll(e) {
if( typeof( e.preventDefault ) != "undefined" ) e.preventDefault();
if( typeof( e.stopImmediatePropagation ) != "undefined" ) e.stopImmediatePropagation();
if( typeof( event ) != "undefined" ) {
if( typeof( event.preventDefault ) != "undefined" ) event.preventDefault();
if( typeof( event.stopImmediatePropagation ) != "undefined" ) event.stopImmediatePropagation();
}
return false;
}
가장 쉬운 해결책은 onWheel={ event => event.currentTarget.blur() }}입력 자체 를 추가 하는 것입니다.