Chrome中不再允许使用selectionStart / selectionEndinputtypes=“数字”

我们的应用程序在input字段上使用selectionStart来确定当用户按下箭头键时是否自动将用户移动到下一个/上一个字段(即,当select在文本的末尾,用户按下我们移动到的右箭头下一个领域,否则)

Chrome现在可以防止在type =“number”处使用selectionStart。 它现在抛出exception:

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

有没有什么方法可以确定插入符号在“数字”types的input字段中的位置?

select只允许使用文本/search,URL,电话和密码 。 对于types编号的input而言,select已被禁用的可能原因是,在某些设备上,或在某些情况下(例如,当input已被列为简短list )时,可能没有插入符号。 我find的唯一解决scheme是将inputtypes更改为文本(使用适当的模式来限制input)。 我仍然在寻找一种方法来处理,而不需要改变inputtypes,当我发现某些东西时会发布更新。

目前唯一可以安全select文本的元素是:

<input type="text|search|password|tel|url">描述如下:
whatwg:selectionStart属性

您还可以阅读HTMLInputElement接口的文档,以深入了解input元素。

为了安全地克服这个“问题”,现在最好的办法是处理一个<input type="text">并应用一个只接受数字的掩码/约束。 有一些插件可以满足要求:

你可以在这里看到一个以前的插件的现场演示:

如果您想安全使用selectionStart ,那么您可以检查支持它的那些元素(请参阅inputtypes属性 )

履行

 // 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); 

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

我们在使用jQuery Numeric Plugin 1.3.x版本时发生这种情况,因此使用try...catch{}包装了selectionStartselectionEnd ,我们能够抑制错误。

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

作为解决scheme, type="tel"inputtypes在Chrome中提供了类似于type="number"非常类似的function,并且没有此限制(Patrice指出)。

有一种方法可以在Chrome上完成(也可能是其他一些浏览器,但Chrome是这里的大罪犯)。 使用window.getSelection()从当前input中检索select对象,然后testing向后(或向前)扩展select,看看select的toString()值是否改变。 如果没有,光标在input的末尾,你可以移动到你的下一个input。 如果是这样,则必须将操作撤消才能撤消select。

 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

我find了一个简单的解决方法(在Chrome上testing) setSelectionRange() 。 在使用setSelectionRange()之前,可以简单地将type更改为text ,然后将其更改回number

这里有一个jQuery的简单例子,当你点击input(在input中添加超过5个数字来查看行为)时,将把插入符号定位在数字input的位置4处。

plunker

我们不能只是将元素检查反转为包含所支持的元素,如下所示:

 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' ) { 

尽pipe这种types的表单字段的被弃用事件的问题可能仍然是相关的,但据我所知,这种字段可以像往常一样用“变更”事件来收听。

我在这里find这篇文章,同时寻找这种types的领域的事件问题的答案,但在testing时,我发现,我可以简单地依靠上述“改变”事件。

我在一个angularjs网站上收到了这个错误。

我已经在input上创build了一个自定义的数据属性,并且还使用了ng-blur(带有$ event)。

当我的callback被称为我试图访问“data-id”的值,如:

 var id = $event.target.attributes["data-id"] 

它应该是这样的:

 var id = $event.target.attributes["data-id"].value 

似乎没有太多关于这个错误的地方,所以我在这里离开这里。