selectionStart/selectionEnd输入类型="数字"不再允许在Chrome中使用

Ste*_*ven 73 javascript google-chrome

我们的应用程序在输入字段上使用selectionStart来确定当用户按下箭头键时是否自动将用户移动到下一个/上一个字段(即,当选择位于文本末尾并且用户按下右箭头时我们移动到下一个字段,否则)

Chrome现在阻止在type ="number"的地方使用selectionStart.它现在抛出异常:

Failed to read the 'selectionStart' property from 'HTMLInputElement': The input element's type ('number') does not support selection.
Run Code Online (Sandbox Code Playgroud)

见如下:

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"的输入字段中确定插入符的位置?

Pat*_*lin 39

仅允许使用文本/搜索,URL,电话和密码进行选择.对于类型编号的输入禁用选择的可能原因是在某些设备上,或者在某些情况下(例如,当输入已经作为简短表示时list),可能没有插入符号.我发现的唯一解决方案是将输入类型更改为文本(使用适当的模式来限制输入).我仍在寻找一种不改变输入类型的方法,并在发现内容时发布更新.

  • 这真的很糟糕.我已经联系了WHAT-WG,因为我认为这是一个重大错误.99.9%的用户代理将`<input type ="number"/>`字段呈现为文本字段,将默认的屏幕键盘(如果可用)设置为数字键盘但仍将该字段呈现为"文本输入"领域.现在,除非我们强制将字段强制回文本并破坏用户体验,否则任何现有/将来尝试为字段添加计算器或类似的值操作功能现在都是无用的. (44认同)
  • Whaaaaat o_0 Chrome刚刚破解了互联网......我的测试.更严重的是,我没有得到逻辑.为什么用户不能选择他们的电子邮件地址或号码?http://stackoverflow.com/questions/22171694/why-shouldnt-a-user-agent-be-able-to-select-an-email-address-or-a-number (6认同)
  • 我知道有些设备可能没有显示插入符号,但它似乎使事情变得复杂.如果我们最终使用type ="text"来解决所有问题,那么它甚至会破坏一个类型的目的.它还失去了手机显示数字输入等不同键盘的能力.我不同意他们选择从输入中删除选择但我不确定解决方案是什么...... (5认同)
  • 我同意你们两个.正如我在[this](http://pchalin.blogspot.com/2014/02/html5-number-input-value-idl-attribute.html)帖子中指出的那样,我认为值IDL属性应始终包含输入包含的任何文本呈现.此外,如果用户代理允许选择,则应该可以使用selectionStart/End. (3认同)

nco*_*hen 18

我找到了一个简单的解决方法(在Chrome上测试)setSelectionRange().你可以简单地改变typetext你使用之前setSelectionRange()再改回number.

这是一个简单的jquery示例,只要您单击输入,就会在数字输入中将插入符号定位在位置4(在输入中添加5个以上的数字以查看行为)

plunker

  • 对我来说(在 Chrome 版本 80 中)这不再有效,因为如果我使用 ```input.type = 'text'``` 将输入类型设置为“文本”,Chrome 将从输入中删除焦点,并且光标消失,因此```input.selectionStart``` 等返回 null。 (2认同)

jhe*_*rax 14

目前唯一允许安全选择文本的元素是:

<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;
}
Run Code Online (Sandbox Code Playgroud)

用法

// 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);
Run Code Online (Sandbox Code Playgroud)

上面的例子可以在这里找到:jsu.fnGetCaretPosition()


jbw*_*ech 5

这是发生了我们,而使用jQuery插件数字,1.3.x版,所以包裹selectionStart,并selectionEndtry...catch{}我们能够压制错误.

资料来源:https://github.com/joaquingatica/jQuery-Plugins/commit/a53f82044759d29ff30bac698b09e3202b456545


Kev*_*ers 5

作为解决方法,type="tel"输入类型提供与type="number"Chrome 非常相似的功能,并且没有此限制(如Patrice所指出的).


Pre*_*101 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
}
Run Code Online (Sandbox Code Playgroud)

我从这个答案得到了这个想法:https: //stackoverflow.com/a/24247942