입력 유형의 selectionStart / selectionEnd = "number"는 더 이상 Chrome에서 허용되지 않습니다.


83

우리의 응용 프로그램은 입력 필드에서 selectionStart를 사용하여 사용자가 화살표 키를 누를 때 다음 / 이전 필드로 자동으로 이동할지 여부를 결정합니다 (즉, 선택이 텍스트의 끝에 있고 사용자가 이동하려는 오른쪽 화살표를 누를 때) 다음 필드, 그렇지 않으면)

Chrome은 이제 type = "number"에서 selectionStart가 사용되지 않도록합니다. 이제 예외가 발생합니다.

Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('number') does not support selection.

다음을 참조하십시오.

https://codereview.chromium.org/100433008/#ps60001

http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#do-not-apply

type = "number"의 입력 필드에서 캐럿의 위치를 ​​결정하는 방법이 있습니까?


3
흠 이것에 대한 업데이트가 없습니다. 이 기능이 제거되는 이유가 궁금합니다.
— Apples

1
또 다른 활용 : 입력 유형 번호와 함께 jquery-maskmoney 플러그인을 사용하면 동일한 문제가 발생합니다
— Alexandre

입력 유형을 일시적으로로 변경 text하고 캐럿 위치를 확인한 다음 유형을 다시 변경할 수 number있습니까?
— Stan

1
@Stan 나는 아직 시도하지 않았지만 스와핑 유형이 매우 효과적이라고 생각하지 않습니다.
— Steven

2
@Steven 작동하지 않습니다. selectionStart / End는 항상 0으로 반환됩니다. jsfiddle.net/Mottie/wMYKU
— Mottie

답변:


43

텍스트 / 검색, URL, 전화 및 암호로만 선택할 수 있습니다 . number 유형 입력에 대해 선택이 비활성화 된 이유는 일부 장치에서 또는 일부 상황 (예 : 입력이 short로 표시되는 경우 list)에서 캐럿이 없을 수 있기 때문입니다. 내가 찾은 유일한 해결책은 입력 유형을 텍스트로 변경하는 것입니다 (입력을 제한하는 적절한 패턴 사용). 나는 여전히 입력 유형을 변경하지 않고 할 수있는 방법을 찾고 있으며 무언가를 찾으면 업데이트를 게시 할 것입니다.


6
일부 장치에 캐럿이 표시되지 않을 수 있지만 상황이 복잡해 보입니다. 우리가 모든 것에 type = "text"를 사용하게된다면 그것은 심지어 유형을 갖는 목적을 무너 뜨립니다. 또한 전화가 숫자 입력 등을 위해 다른 키보드를 표시하는 기능을 잃습니다. 입력에서 선택 항목을 제거하는 선택에 동의하지 않지만 솔루션이 무엇인지 모르겠습니다 ...
— Steven

49
이건 정말 짜증나. 나는 이것이 큰 실수라고 생각하기 때문에 WHAT-WG에 연락했습니다. 사용자 에이전트의 99.9 %는 <input type="number"/>기본 온 스크린 키보드 (사용 가능한 경우)를 숫자 키보드로 설정하는 텍스트 필드로 필드를 렌더링하지만 여전히 필드를 "텍스트 입력"필드로 렌더링합니다. 필드에 대한 계산기 또는 유사한 값 조작 기능을 추가하려는 기존 / 미래 시도는 이제 필드를 텍스트로 되돌리고 사용자 경험을 망치지 않는 한 무용지물이됩니다.
— scunliffe 2014

3
두 분 모두 동의합니다. 이 게시물 에서 지적했듯이 값 IDL 속성은 항상 입력에 포함 된 텍스트 렌더링을 포함해야한다고 생각합니다. 또한 사용자 에이전트가 선택을 허용하면 selectionStart / End를 사용할 수 있어야합니다.
— Patrice Chalin 2014

6
크롬이 방금 인터넷을 깼어요 .. 그리고 내 테스트. 더 심각한 메모에서 나는 논리를 이해하지 못합니다. 사용자가 이메일 주소 나 번호를 선택할 수없는 이유는 무엇입니까? stackoverflow.com/questions/22171694/...
— 피터

22

.NET에 대한 간단한 해결 방법 (Chrome에서 테스트 됨)을 찾았습니다 setSelectionRange(). 당신은 단순히을 변경할 수 있습니다 type에 text사용하기 전에 setSelectionRange()다음에 다시 변경 number.

다음은 입력을 클릭 할 때마다 숫자 입력의 위치 4에 캐럿을 배치하는 jquery를 사용한 간단한 예제입니다 (동작을 보려면 입력에 5 개 이상의 숫자를 추가하십시오).

플 런커


이 접근 방식은 email입력 에도 적용됩니다 (이 페이지 setSelectionRange()에서 Chrome이 아닌 IE11 (!)에서 작동하는 이유를 궁금해하게 된 방법 ).
— jdunning

이것은 순수한 JavaScript obj.type = "text"와 같이 jQuery없이 작동합니다. 그런 다음 obj.type = "number"로 돌아갑니다.
— jacouh 19:43에

그러나 plunkr는 더 이상 사용자가 마우스로 선택하는 것을 허용하지 않습니다.
— Mr Lister

1
나를 위해 (Chrome 버전 80에서)을 사용하여 입력 유형을 "텍스트"로 설정하면 input.type = 'text'Chrome이 입력에서 포커스를 제거하고 커서가 사라 지므로 input.selectionStartetc가 null을 반환 하기 때문에 더 이상 작동하지 않습니다 .
— Ananda Masri

16

현재 텍스트 선택을 안전하게 허용하는 유일한 요소는 다음과 같습니다.

<input type="text|search|password|tel|url">설명 :
whatwg : selectionStart 속성 .

HTMLInputElement 인터페이스 에 대한 설명서를 읽고 입력 요소를 자세히 살펴볼 수도 있습니다.

이 "문제"를 안전하게 극복하기 위해 현재 가장 좋은 방법은 <input type="text">숫자 만 허용하는 마스크 / 제약 조건을 처리 하고 적용하는 것입니다. 요구 사항을 충족하는 몇 가지 플러그인이 있습니다.

여기에서 이전 플러그인 중 하나의 라이브 데모를 볼 수 있습니다.

안전하게 사용하려면이를 selectionStart지원하는 요소를 확인할 수 있습니다 ( 입력 유형 속성 참조 ).

이행

// Fix: failed to read the 'selectionStart' property from 'HTMLInputElement'
// The @fn parameter provides a callback to execute additional code
var _fixSelection = (function() {
    var _SELECTABLE_TYPES = /text|password|search|tel|url/;
    return function fixSelection (dom, fn) {
        var validType = _SELECTABLE_TYPES.test(dom.type),
            selection = {
                start: validType ? dom.selectionStart : 0,
                end: validType ? dom.selectionEnd : 0
            };
        if (validType && fn instanceof Function) fn(dom);
        return selection;
    };
}());

// Gets the current position of the cursor in the @dom element
function getCaretPosition (dom) {
    var selection, sel;
    if ('selectionStart' in dom) {
        return _fixSelection(dom).start;
    } else { // IE below version 9
        selection = document.selection;
        if (selection) {
            sel = selection.createRange();
            sel.moveStart('character', -dom.value.length);
            return sel.text.length;
        }
    }
    return -1;
}

용법

// If the DOM element does not support `selectionStart`,
// the returned object sets its properties to -1.
var box = document.getElementById("price"),
    pos = getCaretPosition(box);
console.log("position: ", pos);

위의 예제는 여기에서 찾을 수 있습니다 : jsu.fnGetCaretPosition ()


안녕하세요, 게시물 주셔서 감사합니다. '숫자 만 허용하는 제약'이 무슨 뜻인지 설명해 주시겠습니까?
— PetarMI 2015

1
안녕하세요 @PetarMI, 제약 에 의해 <input> 요소는 숫자 만 받아 들일 수 있으며 JavaScript를 통해 수행된다는 것을 의미합니다. 모든 브라우저가 새로운 HTML5 <input> 태그와 제대로 작동하는 것은 아니기 때문입니다.
— jherax


5

해결 방법으로 type="tel"입력 유형은 type="number"Chrome에서와 매우 유사한 기능을 제공하며 이러한 제한이 없습니다 (Patrice가 지적한대로).


fwiw 이것은 안드로이드에 전화 특정 숫자 패드를 제공하는 반면 숫자는 다른 숫자 패드를 제공합니다
— patrick

5

Chrome에서이 작업을 수행 할 수있는 한 가지 방법이 있습니다 (그리고 다른 브라우저에서도 가능하지만 Chrome은 여기에서 큰 문제입니다). 사용하여 window.getSelection()현재의 입력으로부터의 선택 객체를 검색하고 테스트 (또는 전방) 선택 뒤쪽으로 연장하고있는 경우 표시되는 toString()선택 변경 값. 그렇지 않은 경우 커서가 입력의 끝에 있으며 다음 입력으로 이동할 수 있습니다. 그렇다면 선택을 취소하려면 작업을 되돌려 야합니다.

s = window.getSelection();
len = s.toString().length;
s.modify('extend', 'backward', 'character');
if (len < s.toString().length) {
    // It's not at the beginning of the input, restore previous selection
    s.modify('extend', 'forward', 'character');
} else {
    // It's at the end, you can move to the previous input
}

나는이 답변 에서이 아이디어를 얻었습니다 : https://stackoverflow.com/a/24247942


3

다음과 같이 지원되는 요소 만 포함하도록 요소 검사를 반대로 할 수는 없습니다.

if (deviceIsIOS &&
    targetElement.setSelectionRange &&
    (
        targetElement.type === 'text' ||
        targetElement.type === 'search' ||
        targetElement.type === 'password' ||
        targetElement.type === 'url' ||
        targetElement.type === 'tel'
    )
) {

대신 :

if (deviceIsIOS && 
    targetElement.setSelectionRange && 
    targetElement.type.indexOf('date') !== 0 && 
    targetElement.type !== 'time' && 
    targetElement.type !== 'month'
) {

1

이 유형의 양식 필드에 대해 사용되지 않는 이벤트와 관련된 문제는 여전히 관련이있을 수 있지만 내가 볼 수있는 한 이러한 유형의 필드는 평소와 같이 "변경"이벤트를 통해 수신 할 수 있습니다.

이 유형의 필드에 대한 이벤트 문제에 대한 답을 찾는 동안 여기에서이 기사를 찾았지만 테스트하는 동안 언급 한대로 "변경"이벤트에 의존 할 수 있다는 것을 발견했습니다.


1

angularjs 웹 사이트에서이 오류를 받았습니다.

입력에 사용자 지정 데이터 속성을 만들고 ng-blur ($ event 사용)도 사용했습니다.

콜백이 호출되었을 때 다음과 같이 'data-id'값에 액세스하려고했습니다.

var id = $event.target.attributes["data-id"]

그리고 다음과 같아야합니다.

var id = $event.target.attributes["data-id"].value

이 오류에 대해 아무데도 많지 않은 것 같으므로 여기에 남겨 둡니다.


0

이 답변이 너무 늦었 음을 알고 있지만 여기에는 대부분의 브라우저 (이전 및 새)에 대해 모든 유형의 요소에 대해 selectionStart를 구현하는 플러그인이 있습니다.

https://github.com/adelriosantiago/caret

type="number"@ncohen의 답변을 사용하여 문제 를 처리하도록 업데이트했습니다 .


0

Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('number') does not support selection.다음과 같이 해결하십시오 .

var checkFocus = false;
var originalValue = "";
$(document).ready(function() {
  $("input").focus(function() {
    var that = this;
    if ($('#' + $(this).context.id).attr("type") == "text") {
      setTimeout(function() {
        if (that.selectionStart != null || that.selectionEnd != null) {
          that.selectionStart = that.selectionEnd = 10000;
        }
      }, 0);
    } else if ($('#' + $(this).context.id).attr("type") == "number") {
      if (checkFocus) {
        moveCursorToEnd($('#' + $(this).context.id), $(this).context.id);
        checkValue($('#' + $(this).context.id))
        checkFocus = false;
      } else {
        $('#' + $(this).context.id).blur();
      }
    }
  });
});

function FocusTextBox(id) {
  checkFocus = true;
  document.getElementById(id).focus();
}

function checkValue(input) {
  if ($(input).val() == originalValue || $(input).val() == "") {
    $(input).val(originalValue)
  }
}

function moveCursorToEnd(input, id) {
  originalValue = input.val();
  input.val('');
  document.getElementById(id).focus();
  return originalValue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<button onclick="FocusTextBox('textid')">
   <input id="textid" type="number" value="1234" > 
</button>


0

Chrome의 기기 테스트 모드를 사용하는 경우 Angular에서 오 탐지에주의하세요.

따라서 이것은 분명히 Chrome이며 실제 iPhone이 아닙니다. 그러나 _platform.IOStrue를 반환하고 setSelectionRange이후에 실패 하기 때문에 오류가 여전히 발생 합니다.

이것은 Angular이지만 다른 프레임 워크 / 환경에서도 유사한 문제가 존재할 수 있습니다.

여기에 이미지 설명 입력

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.