我们的应用程序在输入字段上使用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”的输入字段中确定插入符的位置?
答案 0 :(得分:37)
Selection is only permitted with text/search, URL, tel and password。对于类型编号的输入禁用选择的可能原因是在某些设备上,或在某些情况下(例如,当输入已经显示为短list
)时,可能没有插入符号。我发现的唯一解决方案是将输入类型更改为文本(使用适当的模式来限制输入)。我仍在寻找一种不改变输入类型的方法,并在发现内容时发布更新。
答案 1 :(得分:14)
目前唯一允许安全选择文本的元素是:
<input type="text|search|password|tel|url">
如下所述: whatwg: selectionStart attribute 。
您还可以阅读 HTMLInputElement interface 的文档,详细了解输入元素。
要克服这个问题&#34;问题&#34;安全地,现在最好的是处理<input type="text">
并应用仅接受数字的掩码/约束。有一些插件满足要求:
您可以在此处看到之前插件之一的现场演示:
如果您想安全使用selectionStart
,那么您可以检查支持它的元素(请参阅input type attributes)
// 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()
答案 2 :(得分:14)
我在setSelectionRange()
找到了一个简单的解决方法(在Chrome上测试过)。您可以在使用type
之前将text
更改为setSelectionRange()
,然后将其更改回number
。
这是一个简单的jquery示例,只要您单击输入(在输入中添加超过5个数字以查看行为),就会在数字输入中将插入符号定位在第4位
答案 3 :(得分:5)
在使用jQuery Numeric Plugin版本1.3.x时,我们发生了这种情况,因此将selectionStart
和selectionEnd
与try...catch{}
包裹起来,我们就能够抑制错误。
来源:https://github.com/joaquingatica/jQuery-Plugins/commit/a53f82044759d29ff30bac698b09e3202b456545
答案 4 :(得分:5)
作为解决方法,type="tel"
输入类型提供与Chrome中type="number"
非常相似的功能,并且没有此限制(正如Patrice所指出的那样)。
答案 5 :(得分: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
答案 6 :(得分: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'
) {
答案 7 :(得分:1)
虽然这种类型的表单字段的已弃用事件的问题可能仍然相关,但据我所知,可以通过&#34;更改&#34;来收听此类字段。事件,像往常一样。
我在这里找到这篇文章的事件问题的答案,但在测试时,我发现我可以简单地依靠&#34;改变&#34;如上所述。
答案 8 :(得分:1)
我在angularjs网站上收到此错误。
我在输入上创建了自定义数据属性,并且还使用了ng-blur(使用$ event)。
当我的回调被调用时,我试图访问'data-id'值,如:
var id = $event.target.attributes["data-id"]
应该是这样的:
var id = $event.target.attributes["data-id"].value
这个错误在任何地方似乎都没有太多,所以我要离开这里。
答案 9 :(得分:1)
修改selectionStart
对象中的type属性可以获得光标位置(selectionEnd
,event.target
):
const input = document.querySelector("input");
input.addEventListener("keyup", (e) => {
const {target} = e;
target.setAttribute("type", "text")
console.log(target.selectionStart, target.selectionEnd)
});
<input type="number" />
答案 10 :(得分:0)
我知道这个答案来得太晚了,但是对于大多数浏览器(旧的和新的)来说,这是一个为所有类型的元素实现selectionStart的插件:
https://github.com/adelriosantiago/caret
我已使用@ncohen的回答更新了它以处理type="number"
问题。
答案 11 :(得分: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>
答案 12 :(得分:0)