우리의 응용 프로그램은 입력 필드에서 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”의 입력 필드에서 캐럿의 위치를 결정하는 방법이 있습니까?
답변
텍스트 / 검색, URL, 전화 및 암호로만 선택할 수 있습니다 . number 유형 입력에 대해 선택이 비활성화 된 이유는 일부 장치에서 또는 일부 상황 (예 : 입력이 short로 표시되는 경우 list
)에서 캐럿이 없을 수 있기 때문입니다. 내가 찾은 유일한 해결책은 입력 유형을 텍스트로 변경하는 것입니다 (입력을 제한하는 적절한 패턴 사용). 나는 여전히 입력 유형을 변경하지 않고 할 수있는 방법을 찾고 있으며 무언가를 찾으면 업데이트를 게시 할 것입니다.
답변
.NET에 대한 간단한 해결 방법 (Chrome에서 테스트 됨)을 찾았습니다 setSelectionRange()
. 당신은 단순히을 변경할 수 있습니다 type
에 text
사용하기 전에 setSelectionRange()
다음에 다시 변경 number
.
다음은 입력을 클릭 할 때마다 숫자 입력의 위치 4에 캐럿을 배치하는 jquery를 사용한 간단한 예제입니다 (동작을 보려면 입력에 5 개 이상의 숫자를 추가하십시오).
답변
현재 텍스트 선택을 안전하게 허용하는 유일한 요소는 다음과 같습니다.
<input type="text|search|password|tel|url">
설명 :
whatwg : selectionStart 속성 .
HTMLInputElement 인터페이스 에 대한 설명서를 읽고 입력 요소를 자세히 살펴볼 수도 있습니다.
이 “문제”를 안전하게 극복하기 위해 현재 가장 좋은 방법은 <input type="text">
숫자 만 허용하는 마스크 / 제약 조건을 처리 하고 적용하는 것입니다. 요구 사항을 충족하는 몇 가지 플러그인이 있습니다.
- http://digitalbush.com/projects/masked-input-plugin/
- http://jherax.github.io/#jqueryfnnumericinput-
- http://firstopinion.github.io/formatter.js/
- 그 외 수많은 …
여기에서 이전 플러그인 중 하나의 라이브 데모를 볼 수 있습니다.
안전하게 사용하려면이를 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 ()
답변
이는 jQuery Numeric Plugin, 버전 1.3.x를 사용하는 동안 발생했기 때문에 selectionStart
및 selectionEnd
로 래핑 try...catch{}
하여 오류를 억제 할 수있었습니다.
출처 : https://github.com/joaquingatica/jQuery-Plugins/commit/a53f82044759d29ff30bac698b09e3202b456545
답변
해결 방법으로 type="tel"
입력 유형은 type="number"
Chrome에서와 매우 유사한 기능을 제공하며 이러한 제한이 없습니다 (Patrice가 지적한대로).
답변
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
답변
다음과 같이 지원되는 요소 만 포함하도록 요소 검사를 반대로 할 수는 없습니다.
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'
) {