Nasza aplikacja korzysta z selectionStart na polach wejściowych, aby określić, czy automatycznie przenieść użytkownika do następnego / poprzedniego pola po naciśnięciu klawiszy strzałek (tj. Gdy zaznaczenie jest na końcu tekstu, a użytkownik naciśnie strzałkę w prawo, do następne pole, w przeciwnym razie)
Chrome zapobiega teraz używaniu selectionStart, gdzie type = "number". Teraz zgłasza wyjątek:
Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('number') does not support selection.
Zobacz następujące:
https://codereview.chromium.org/100433008/#ps60001
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#do-not-apply
Czy istnieje sposób na określenie położenia daszka w polu wejściowym typu = "liczba"?
javascript
google-chrome
Steven
źródło
źródło
text
, sprawdzić pozycję kursora, a następnie zmienić typ z powrotem nanumber
?Odpowiedzi:
Wybór jest dozwolony tylko w przypadku tekstu / wyszukiwania, adresu URL, numeru tel i hasła . Prawdopodobną przyczyną wyłączenia wyboru dla wejść typu numer jest to, że na niektórych urządzeniach lub w pewnych okolicznościach (np. Gdy wejście jest przedstawiane jako krótkie
list
), może nie być daszka. Jedynym rozwiązaniem, jakie znalazłem, była zmiana typu wprowadzania na tekst (z odpowiednim wzorcem ograniczającym wprowadzanie). Nadal szukam sposobu na obejście się bez zmiany typu danych wejściowych i opublikuję aktualizację, gdy coś znajdę.źródło
<input type="number"/>
pole jako pole tekstowe, które ustawia domyślną klawiaturę ekranową (jeśli jest dostępna) na klawiaturę numeryczną, ale nadal renderuje to pole jako pole do wprowadzania tekstu. Wszelkie istniejące / przyszłe próby dodania kalkulatora lub podobnej funkcji manipulowania wartością dla pola są teraz bezużyteczne, chyba że wymuszamy powrót pola do tekstu i zrujnujemy doświadczenie użytkownika.Znalazłem proste obejście (przetestowane w Chrome) dla
setSelectionRange()
. Można po prostu zmienićtype
, abytext
przed użyciemsetSelectionRange()
, a następnie zmienić go z powrotem donumber
.Oto prosty przykład z jquery, który ustawi kursor na pozycji 4 w polu wprowadzania liczb za każdym razem, gdy klikniesz na wejście (dodaj więcej niż 5 liczb w danych wejściowych, aby zobaczyć zachowanie)
plunker
źródło
email
danych wejściowych (w ten sposób skończyłem na tej stronie, zastanawiając się, dlaczegosetSelectionRange()
działało w IE11 (!), A nie w Chrome).input.type = 'text'
, Chrome usuwa fokus z wejścia, a kursor znika, więcinput.selectionStart
etc zwraca wartość null.Obecnie jedynymi elementami, które umożliwiają bezpieczne zaznaczanie tekstu, są:
<input type="text|search|password|tel|url">
jak opisano watrybucie: whatwg: selectionStart .
Możesz również przeczytać dokumentację interfejsu HTMLInputElement, aby przyjrzeć się bliżej elementom wejściowym.
Aby bezpiecznie przezwyciężyć ten „problem”, najlepiej na razie poradzić sobie z
<input type="text">
maską / ograniczeniem, które akceptują tylko liczby. Istnieje kilka wtyczek, które spełniają wymagania:Możesz zobaczyć demonstrację na żywo jednej z poprzednich wtyczek tutaj:
Jeśli chcesz używać bezpiecznie
selectionStart
, możesz sprawdzić te elementy, które go obsługują (zobacz atrybuty typu danych wejściowych )Realizacja
// 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; }
Stosowanie
// 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);
Powyższy przykład można znaleźć tutaj: jsu.fnGetCaretPosition ()
źródło
To się dzieje za nami podczas korzystania z jQuery numeryczna Plugin w wersji 1.3.x, tak owijania
selectionStart
iselectionEnd
literę Atry...catch{}
byliśmy w stanie stłumić błąd.Źródło: https://github.com/joaquingatica/jQuery-Plugins/commit/a53f82044759d29ff30bac698b09e3202b456545
źródło
Aby obejść ten problem ,
type="tel"
typ wejścia zapewnia bardzo podobną funkcjonalność dotype="number"
Chrome i nie ma tego ograniczenia (jak wskazał Patrice).źródło
Jest jeden sposób, w jaki możesz to zrobić w Chrome (i być może w niektórych innych przeglądarkach, ale Chrome jest tutaj największym przestępcą). Użyj,
window.getSelection()
aby pobrać obiekt zaznaczenia z bieżącego wejścia, a następnie przetestuj, wydłuż wybór do tyłu (lub do przodu) i zobacz, czytoString()
wartość zaznaczenia się zmienia. Jeśli tak nie jest, kursor znajduje się na końcu wejścia i możesz przejść do następnego wejścia. Jeśli tak, musisz cofnąć operację, aby cofnąć wybór.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 }
Wpadłem na ten pomysł z tej odpowiedzi SO: https://stackoverflow.com/a/24247942
źródło
nie możemy po prostu odwrócić sprawdzania elementów, aby po prostu uwzględnić elementy, które są obsługiwane, na przykład:
if (deviceIsIOS && targetElement.setSelectionRange && ( targetElement.type === 'text' || targetElement.type === 'search' || targetElement.type === 'password' || targetElement.type === 'url' || targetElement.type === 'tel' ) ) {
zamiast tego:
if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month' ) {
źródło
Chociaż problem z przestarzałymi zdarzeniami dla tego typu pól formularza może być nadal aktualny, o ile widzę, tego rodzaju pola można jak zwykle odsłuchać za pomocą zdarzenia „change”.
Dotarłem do tego artykułu tutaj, szukając odpowiedzi na problem zdarzeń dla tego typu pola, ale testując go stwierdziłem, że mogę po prostu polegać na zdarzeniu „zmiana”, o którym mowa.
źródło
Otrzymałem ten błąd w witrynie angularjs.
Utworzyłem niestandardowy atrybut danych na wejściu i użyłem również ng-blur (z $ event).
Kiedy wywołano moje wywołanie zwrotne, próbowałem uzyskać dostęp do wartości „data-id”, na przykład:
var id = $event.target.attributes["data-id"]
A powinno wyglądać tak:
var id = $event.target.attributes["data-id"].value
Wydaje się, że nigdzie nie ma zbyt wiele na temat tego błędu, więc zostawiam to tutaj.
źródło
Wiem, że ta odpowiedź przychodzi za późno, ale tutaj jest wtyczka, która implementuje selectionStart dla wszystkich typów elementów, dla większości przeglądarek (starych i nowych):
https://github.com/adelriosantiago/caret
Zaktualizowałem go, aby rozwiązać
type="number"
problem, używając odpowiedzi @ncohen.źródło
Rozwiąż
Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('number') does not support selection.
w następujący sposób: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>
źródło
Uważaj na fałszywie pozytywne wyniki w Angular, jeśli używasz trybu testowania urządzenia Chrome.
Jest to oczywiście Chrome, a nie rzeczywisty iPhone - jednak błąd nadal jest zgłaszany, ponieważ
_platform.IOS
zwraca wartość true, a następniesetSelectionRange
kończy się niepowodzeniem.To jest Angular - ale podobne problemy mogą występować w innych frameworkach / środowiskach.
źródło