입력 유형의 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(). 당신은 단순히을 변경할 수 있습니다 typetext사용하기 전에 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.