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">
并应用一个只接受数字的掩码/约束。 有一些插件可以满足要求:
- http://digitalbush.com/projects/masked-input-plugin/
- http://jherax.github.io/#jqueryfnnumericinput-
- http://firstopinion.github.io/formatter.js/
- 和其他吨…
你可以在这里看到一个以前的插件的现场演示:
如果您想安全使用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{}
包装了selectionStart
和selectionEnd
,我们能够抑制错误。
来源: 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
似乎没有太多关于这个错误的地方,所以我在这里离开这里。