Unsere Anwendung verwendet selectionStart für Eingabefelder, um zu bestimmen, ob der Benutzer automatisch zum nächsten / vorherigen Feld verschoben werden soll, wenn er die Pfeiltasten drückt (dh wenn sich die Auswahl am Ende des Textes befindet und der Benutzer den Pfeil nach rechts drückt, zu dem wir wechseln das nächste Feld, sonst)
Chrome verhindert jetzt, dass selectionStart verwendet wird, wenn type = "number". Es wird jetzt die Ausnahme ausgelöst:
Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('number') does not support selection.
Siehe folgendes:
https://codereview.chromium.org/100433008/#ps60001
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#do-not-apply
Gibt es eine Möglichkeit, die Position des Carets in einem Eingabefeld vom Typ = "Nummer" zu bestimmen?
javascript
google-chrome
Steven
quelle
quelle
text
, die Caret-Position überprüfen und dann den Typ wieder auf ändernnumber
?Antworten:
Die Auswahl ist nur mit Text / Suche, URL, Telefon und Passwort erlaubt . Der wahrscheinliche Grund dafür, dass die Auswahl für Eingaben mit der Typennummer deaktiviert wurde, ist, dass auf einigen Geräten oder unter bestimmten Umständen (z. B. wenn die Eingabe als Kurzdarstellung dargestellt wurde
list
) möglicherweise kein Caret vorhanden ist. Die einzige Lösung, die ich gefunden habe, bestand darin, den Eingabetyp in Text zu ändern (mit einem geeigneten Muster, um die Eingabe einzuschränken). Ich bin immer noch auf der Suche nach einer Möglichkeit, ohne den Eingabetyp zu ändern, und werde ein Update veröffentlichen, wenn ich etwas finde.quelle
<input type="number"/>
Feld als Textfeld, das die Standard-Bildschirmtastatur (falls verfügbar) auf die numerische Tastatur setzt, das Feld jedoch weiterhin als "Texteingabe" -Feld rendert. Jeder bestehende / zukünftige Versuch, einen Taschenrechner oder eine ähnliche Wertmanipulationsfunktion für das Feld hinzuzufügen, wird jetzt unbrauchbar, es sei denn, wir zwingen das Feld zurück zum Text und ruinieren die Benutzererfahrung.Ich habe eine einfache Problemumgehung (auf Chrome getestet) für gefunden
setSelectionRange()
. Sie können dastype
to einfach ändern ,text
bevor Sie es verwenden,setSelectionRange()
und es dann wieder ändernnumber
.Hier ist ein einfaches Beispiel mit jquery, das das Caret bei jedem Klick auf die Eingabe an Position 4 in der Zahleneingabe positioniert (fügen Sie mehr als 5 Zahlen in die Eingabe ein, um das Verhalten zu sehen).
Plunker
quelle
email
Eingaben (so kam ich auf diese Seite und fragte mich, warumsetSelectionRange()
in IE11 (!) Und nicht in Chrome funktioniert wurde).input.type = 'text'
Chrome den Fokus von der Eingabe entfernt und der Cursor verschwindet, sodassinput.selectionStart
etc null zurückgibt, wenn ich den Eingabetyp mit auf "Text" setze .Derzeit sind die einzigen Elemente, die eine sichere Textauswahl ermöglichen, folgende:
<input type="text|search|password|tel|url">
wie beschrieben in:whatwg: selectionStart-Attribut .
Sie können auch die Dokumentation für die HTMLInputElement-Schnittstelle lesen, um die Eingabeelemente genauer zu betrachten.
Um dieses "Problem" sicher zu lösen, sollten Sie sich vorerst mit einer
<input type="text">
Maske / Einschränkung befassen , die nur Zahlen akzeptiert. Es gibt einige Plugins, die die Anforderungen erfüllen:Sie können eine Live-Demo eines der vorherigen Plugins hier sehen:
Wenn Sie sicher verwenden möchten, können
selectionStart
Sie nach den Elementen suchen, die dies unterstützen (siehe Eingabetypattribute ).Implementierung
// 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; }
Verwendung
// 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);
Das obige Beispiel finden Sie hier: jsu.fnGetCaretPosition ()
quelle
Dies geschah für uns, als wir das jQuery Numeric Plugin, Version 1.3.x, verwendeten. Um das
selectionStart
undselectionEnd
mit einem zu verpacken, konntentry...catch{}
wir den Fehler unterdrücken.Quelle: https://github.com/joaquingatica/jQuery-Plugins/commit/a53f82044759d29ff30bac698b09e3202b456545
quelle
Um dieses
type="tel"
Problem zu umgehen, bietet der Eingabetyp eine sehr ähnliche Funktionalität wietype="number"
in Chrome und weist diese Einschränkung nicht auf (wie von Patrice hervorgehoben).quelle
Es gibt eine Möglichkeit, dies in Chrome zu erreichen (und möglicherweise in einigen anderen Browsern, aber Chrome ist hier der große Täter). Verwenden Sie
window.getSelection()
diese Option , um das Auswahlobjekt von der aktuellen Eingabe abzurufen und anschließend die Auswahl rückwärts (oder vorwärts) zu erweitern und festzustellen, ob sich dertoString()
Wert der Auswahl ändert. Ist dies nicht der Fall, befindet sich der Cursor am Ende der Eingabe und Sie können zur nächsten Eingabe wechseln. Wenn dies der Fall ist, müssen Sie den Vorgang umkehren, um die Auswahl rückgängig zu machen.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 }
Ich habe diese Idee aus dieser SO-Antwort erhalten: https://stackoverflow.com/a/24247942
quelle
Können wir die Elementprüfung nicht einfach umkehren, um nur die unterstützten Elemente einzuschließen, wie folgt:
if (deviceIsIOS && targetElement.setSelectionRange && ( targetElement.type === 'text' || targetElement.type === 'search' || targetElement.type === 'password' || targetElement.type === 'url' || targetElement.type === 'tel' ) ) {
an Stelle von:
if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month' ) {
quelle
Während das Problem mit den veralteten Ereignissen für diese Art von Formularfeld nach wie vor relevant sein kann, kann diese Art von Feld meines Erachtens wie gewohnt mit dem Ereignis "Ändern" abgehört werden.
Ich bin hier zu diesem Artikel gekommen, als ich nach einer Antwort auf das Ereignisproblem für diesen Feldtyp gesucht habe, aber beim Testen habe ich festgestellt, dass ich mich einfach auf das erwähnte "Änderungs" -Ereignis verlassen kann.
quelle
Ich habe diesen Fehler auf einer AngularJS-Website erhalten.
Ich hatte ein benutzerdefiniertes Datenattribut für eine Eingabe erstellt und verwendete auch ng-blur (mit $ event).
Als mein Rückruf aufgerufen wurde, habe ich versucht, auf den Wert 'data-id' zuzugreifen, wie:
var id = $event.target.attributes["data-id"]
Und es hätte so sein sollen:
var id = $event.target.attributes["data-id"].value
Es scheint nirgendwo zu viel über diesen Fehler zu sein, also lasse ich das hier.
quelle
Ich weiß, dass diese Antwort zu spät kommt, aber hier ist ein Plug-In, das selectionStart für alle Arten von Elementen implementiert, für die meisten Browser (alt und neu):
https://github.com/adelriosantiago/caret
Ich habe es aktualisiert, um das
type="number"
Problem mithilfe der Antwort von @ncohen zu beheben.quelle
Löse
Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('number') does not support selection.
wie folgt: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>
quelle
Achten Sie in Angular auf falsch positive Ergebnisse, wenn Sie den Gerätetestmodus von Chrome verwenden.
Dies ist also eindeutig Chrome und kein tatsächliches iPhone - dennoch wird der Fehler immer noch ausgelöst, da
_platform.IOS
true zurückgegeben wird undsetSelectionRange
anschließend fehlschlägt.Dies ist Angular - ähnliche Probleme können jedoch auch in anderen Frameworks / Umgebungen auftreten.
quelle