programing

' 서스크사안함에용롤'에서 안 함' 서스크사안함에용롤'에서 안 함' 서스크사안함에용롤'에서 안 함```

oldcodes 2023. 8. 27. 09:52
반응형

' 서스크사안함에용롤'에서 안 함`

입력 번호 필드의 숫자를 변경하는 스크롤 휠을 비활성화할 수 있습니까?스피너를 제거하기 위해 웹킷 전용 CSS를 사용했지만 이 동작을 완전히 없애고 싶습니다.사용하는 것을 좋아합니다.type=number에. iOS에서

다른 사용자가 제안한 것과 같은 입력 번호 요소에서 마우스 휠 이벤트의 기본 동작을 방지합니다(일반적으로 "blur()"를 호출하는 것은 사용자가 원하는 것이 아니기 때문에 선호하는 방법이 아닙니다).

그러나 모든 입력 번호 요소에서 마우스 휠 이벤트를 듣는 것은 항상 피하고 요소가 포커스에 있을 때만(문제가 존재할 때) 이를 수행합니다.그렇지 않으면 마우스 포인터가 입력 번호 요소 위에 있을 때 페이지를 스크롤할없습니다.

jQuery용 솔루션:

// disable mousewheel on a input number field when in focus
// (to prevent Chromium 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')
})

(주요 이벤트를 주변 양식 요소로 위임 - 성능에 좋지 않은 많은 이벤트 청취자에게 방지합니다.)

하나의 이벤트 수신기가 모든 이벤트를 제어합니다.

이것은 순수한 js에서의 @Simon Perepelitsa의 답변과 비슷하지만, 모든 입력에 대해 하나의 이벤트 청취자를 문서 요소에 배치하고 초점이 맞는 요소가 숫자 입력 tpye인지 확인하기 때문에 조금 더 간단합니다.

document.addEventListener("wheel", function(event){
    if(document.activeElement.type === "number"){
        document.activeElement.blur();
    }
});

클래스/id별로 일부 필드에서 값 스크롤 동작을 해제하고 다른 필드에서는 값 스크롤 동작을 해제하려면 다음을 추가합니다.&&대신 해당 문서 선택기를 사용합니다.

document.addEventListener("wheel", function(event){
    if(document.activeElement.type === "number" &&
       document.activeElement.classList.contains("noscroll"))
    {
        document.activeElement.blur();
    }
});

이것으로:

<input type="number" class="noscroll"/>

입력에 noscroll 클래스가 있으면 스크롤 시 변경되지 않으며, 그렇지 않으면 모든 것이 동일하게 됩니다.

JSFidle을 사용하여 여기서 테스트

$(document).on("wheel", "input[type=number]", function (e) {
    $(this).blur();
});

HTML onwheel 속성을 사용하면 됩니다.

이 선택사항은 페이지의 다른 요소 위로 스크롤하는 데 영향을 주지 않습니다.

그리고 모든 입력에 대해 청취자를 추가합니다. 동적으로 생성된 입력에서는 작동하지 않습니다.

또한 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()" />

다른 제안이 있습니다.블러 이벤트를 발생시키는 대부분의 일반적인 권장 사항에서 제가 보는 문제는 예상치 못한 부작용이 있다는 것입니다.포커스 상태를 예기치 않게 제거하는 것이 항상 좋은 것은 아닙니다.

대신에 이것은 왜 안됩니까?

<input type="number" onwheel="return false;" />

그것은 매우 간단하고 간단하며 실행하기 쉽고 부작용이 없습니다.

input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(event){ this.blur() })

http://jsfiddle.net/bQbDm/2/

jQuery 예제 및 크로스 브라우저 솔루션의 경우 관련 질문을 참조하십시오.

번호 입력 스크롤용 HTML5 이벤트 수신기 - Chrome 전용

@세▁pere 페레펠리차

이에 대한 더 나은 해결책이 있습니다.블러는 입력에서 포커스를 제거하며, 이는 사용자가 원하지 않는 부작용입니다.대신 evt.preventDefault를 사용해야 합니다.이렇게 하면 사용자가 스크롤할 때 입력의 기본 동작이 방지됩니다.코드는 다음과 같습니다.

input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(evt){ evt.preventDefault(); })

리액트JS 솔루션

리액트 솔루션이 필요한 고객을 위해 다음과 같은 솔루션이 있습니다.onWheel의 의러들의 type="number"숫자가 변경되는 것을 방지하고 사용자가 입력을 넘기려고 하는 동안 페이지가 스크롤되는 것을 방지하기 위한 입력입니다.마지막으로 사용자가 원하는 대로 편집할 수 있도록 입력에 다시 초점을 맞춥니다.

const numberInputOnWheelPreventChange = (e) => {
  // Prevent the input value change
  e.target.blur()

  // Prevent the page/container scrolling
  e.stopPropagation()

  // Refocus immediately, on the next tick (after the current function is done)
  setTimeout(() => {
    e.target.focus()
  }, 0)
}

return <input type="number" onWheel={numberInputOnWheelPreventChange}/>

리액트와 함께 일하고 해결책을 찾는 모든 사람을 위한 것입니다.가장 쉬운 방법은 다음과 같이 입력 구성 요소의 WheelCapture prop에서 사용하는 것입니다.

onWheelCapture={e => { e.target.blur() }}

먼저 다음 중 하나를 통해 마우스 휠 이벤트를 중지해야 합니다.

  1. 으로 사용 안mousewheel.disableScroll
  2. 로가기채로 e.preventDefault();
  3. el.blur();

처음 두 가지 접근 방식은 창 스크롤을 중지하고 마지막 두 가지 접근 방식은 모두 요소에서 포커스를 제거합니다. 이 두 가지는 모두 바람직하지 않은 결과입니다.

가지 방법은 한가해방은을 사용하는 입니다.el.blur()지연 후 요소에 다시 초점을 맞춥니다.

$('input[type=number]').on('mousewheel', function(){
  var el = $(this);
  el.blur();
  setTimeout(function(){
    el.focus();
  }, 10);
});

가장 쉬운 솔루션은 추가하는 것입니다.onWheel={ event => event.currentTarget.blur() }}입력 자체로.

유형 변화

안전을 알아야 그렇지 HTML과 관련된 볼 수 . 그렇지 않으면 많은 정보를 볼 수 있습니다.Property 'type' does not exist on type 'Element'오류 유형.

document.addEventListener("wheel", function(event){
  const numberInput = (<HTMLInputElement>document.activeElement);
  if (numberInput.type === "number") {
    numberInput.blur();
  }
});

제 경우에는 초점을 유지하면서 스크롤을 계속 적용해야 했습니다.위의 솔루션 중 어느 것도 그것을 처리할 수 없으며 블러/포커스를 하는 것은 저에게 약간 진부하게 느껴집니다.

이렇게 하면 기존 포커스가 유지되고 스크롤도 유지됩니다.있잖아요...브라우저가 해야 하는 것처럼.크롬에서만 최소한의 테스트를 거쳤으며 Y축만 지원합니다.

// you could make this target a specific input instead of document
document.addEventListener('wheel', event => {
  if (!event.target) return;
  const isNumberInput = event.target.nodeName === 'INPUT' && event.target.type === 'number';
  const isFocused = event.target === document.activeElement;
  if (isNumberInput && isFocused) {
    // prevent stupid input change
    event.preventDefault();
    // since we're taking over scrolling, we want to make sure
    // nothing else gets the event
    event.stopPropagation();
    // finally we reapply the scroll
    applyScroll(event);
  }
}, { passive: false });

// this walks up the tree for event.target to find the first
// scrollable parent.  this is probably good enough for most situations.
const applyScroll = event => {
  try {
    // console.debug('attempting to reapply scroll. searching for scrollable container...');
    let scrollContainer = event.target;
    while (scrollContainer && scrollContainer !== document.body && !elementIsScrollable(scrollContainer)) {
      scrollContainer = scrollContainer.parentElement;
      // console.debug('\t-> container was not scrollable. checking parent', scrollContainer);
    }
    if (scrollContainer) {
      // console.debug('scrollContainer container found. applying scroll', scrollContainer, event.deltaY);
      scrollContainer.scrollBy({ top: event.deltaY });
    }
    else {
      // console.debug('no scrollContainer found');
    }
  }
  catch (err) {
    console.info('failed to reapply scroll', err, event);
  }
};

const elementIsScrollable = element => {
  const { scrollHeight = 0, offsetHeight = 0 } = element;
  const scrollable = style.overflowY === 'auto' || style.overflowY === 'scroll';
  return scrollable && scrollHeight > 0 && offsetHeight > 0 && element.scrollHeight > element.offsetHeight;
};

제공된 답변은 Firefox(Quantum)에서 작동하지 않습니다.이벤트 수신기를 마우스 휠에서 휠로 변경해야 합니다.

$(':input[type=number]').on('wheel',function(e){ $(this).blur(); });

이 코드는 Firefox Quantum 및 Chrome에서 작동합니다.

이 해결하려고 하던 중, 실제로 도, 를 부모 을 비활성화하는하다는 것을 알게 . 동시에 부모 요소에서 캡처된 이벤트를 다시 실행하여 숫자 변경을 비활성화했습니다.<input type="number"/>그것이 잡힌 것은, 단순히 다음과 같습니다.

e.target.parentElement.dispatchEvent(e);

그러나 브라우저 콘솔에 오류가 발생하여 의도적으로 잘못된 코드이므로 모든 곳에서 작동하지 않을 수 있습니다(Firefox에서만 테스트했습니다).

적어도 파이어폭스와 크롬에서 잘 작동하는 또 다른 해결책은 임시로 만드는 것입니다.<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포커스가 있는 숫자 입력에 대한 이벤트와 마우스 커서 아래(위의 세 가지 조건이 의미함), 사용자 경험에 대한 부정적인 영향은 거의 없습니다.

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브라우저는 성능상의 이유로 스크롤하는 동안 다시 계산하지 않기 때문에 사용자가 스크롤할 때 스타일이 실행되지 않아야 하지만, 저는 크로스 브라우저/디바이스를 완전히 테스트하지는 않았습니다.

비JS 솔루션

iOS에서 멋진 키보드를 보여주기 때문에 type= number를 사용하는 것을 좋아합니다.

키보드가 정말 멋집니다.그러나 다음과 같은 경우에도 동일한 동작을 수행할 수 있습니다.

<input inputmode="numeric" pattern="[0-9]*" />

MUI 문서에 연결된 gov.uk 에서 가져온 것입니다.우리 제품에 잘 맞습니다.

소금 알갱이

에 대한 브라우저 지원을 확인하십시오. 대부분의 모바일 브라우저가 지원됩니다.inputmode대부분 모바일 경험에 관한 것입니다.YMMV.

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

대부분의 대답은 커서가 숫자 요소 위에 있지 않더라도 숫자 요소를 흐리게 합니다. 아래는 그렇지 않습니다.

document.addEventListener("wheel", function(event) {
  if (document.activeElement.type === "number" &&
    document.elementFromPoint(event.x, event.y) == document.activeElement) {
    document.activeElement.blur();
  }
});

https://jsfiddle.net/s06puv3j/1/

저는 그 해결책에 고심하고 있었습니다.그래서, 이것과 다른 게시물들이 제가 이것을 할 수 있도록 도와줍니다.우리는 여기서 최선의 답에 대해 몇 가지를 바꿔야 합니다.따라서 스크롤을 사용하지 않으려면 다음을 추가해야 합니다.

<script>
$(document).ready(function() {
    $('input[type=number]').on('wheel',function(e){ $(this).blur(); }); 
});
</script>

"온휠"을 사용하는 대신 "휠"을 사용합니다 :)

앤트 / 대응 + 스크립트 답변 입력

    const myComponent = () => {
      const inputRef: React.RefObject<HTMLInputElement> = createRef();
      
      return <Input
         ref={inputRef}
         type="number"
         onWheel={(e) => {
           if (inputRef && inputRef.current && inputRef.current.blur) {
             inputRef.current.blur();
           }
           e.preventDefault();
          }}
      />
    }

각해.그들 모두를 지배하라는 하나의 지시!

다른 솔루션과 달리 이 솔루션을 사용하면 사용자가

  • 입력에 대한 포커스를 늦추지 않습니다.
  • 여전히 스크롤할 수 있습니다!

StackBlitz에서 보기


import { Directive, ElementRef, NgZone, OnDestroy } from '@angular/core';
import { fromEvent, Subscription, takeUntil } from 'rxjs';
import { tap, switchMap } from 'rxjs/operators';

@Directive({
  selector: 'input[type=number]',
})
export class FixNumberInputScrollDirective implements OnDestroy {
  private subs = new Subscription();

  constructor(elRef: ElementRef<HTMLInputElement>, zone: NgZone) {
    const el = elRef.nativeElement;
    const focus$ = fromEvent(el, 'focus');
    const blur$ = fromEvent(el, 'blur');

    // when input is focused, start listening to the scroll of element. On this event blur and
    // re-focus on the next tick. This allows for the page scroll to still happen, but the unwanted
    // input number change is prevented.
    // Stop listening to the scroll when focus is lost
    const preventWheel$ = focus$.pipe(
      switchMap(() => {
        return fromEvent(el, 'wheel', { passive: false }).pipe(
          tap(() => {
            zone.runOutsideAngular(() => {
              el.blur();
              setTimeout(() => {
                el.focus();
              }, 0);
            })
          }),
          takeUntil(blur$)
        );
      })
    );

    this.subs.add(preventWheel$.subscribe());
  }

  ngOnDestroy() {
    this.subs.unsubscribe();
  }
}
const disableNumberInputChangeOnMouseScroll = (): void => {
    let currentFocus: EventTarget | null = null;

    document.addEventListener("focusin", (event) => {
        currentFocus = event.target;
    });

    document.addEventListener("wheel", (_event) => {
        const activeElement = document.activeElement;
        if (activeElement?.tagName === "INPUT" && (activeElement as HTMLInputElement).type === "number") {
            const numberInput = activeElement as HTMLInputElement;
            // blur removes focus from the input, preventing the scroll from changing the value.
            numberInput.blur();
            if (currentFocus === numberInput) {
                // but at the same time, if the caret (https://en.wikipedia.org/wiki/Caret_navigation) was in the input,
                // we want to make sure the focus is restored.
                window.setTimeout(() => numberInput.focus({ preventScroll: true }), 1);
            }
        }
    });
};

숫자 입력은 스크롤 시 변경되지 않지만 캐럿이 입력에 있으면 사용자가 포커스를 잃지 않습니다.

언급URL : https://stackoverflow.com/questions/9712295/disable-scrolling-on-input-type-number

반응형