FED实验室 - 专注WEB端开发和用户体验

实时监听输入框值变化的兼容性方案

JAVASCRIPT 煦涵 5489℃ 0评论

最近在项目中需要实时监听输入框的值的变化,首先想到的是onchange,onblur,onkeydown,onkeyup,onpress等一系列常见事件,但是使用这些往往达不到实时监听的效果。

onchange事件:
只在键盘或者鼠标操作改变对象属性,且失去焦点时触发,js脚本触发无效。

onkeydown/onkeypress/onkeyup事件:
在处理复制、粘贴、拖拽、长按键(按住键盘不放)等细节上并不完善。

onpropertychange事件:
使用该事件某些情况下解决上面存在的问题,不用考虑是否失去焦点,不管js操作还是键盘鼠标手动操作,只要HTML元素属性发生改变即可立即捕获到。但是该事件是IE专属事件,其它浏览器不支持。
需要注意的是:
1. input设置[disabled=true]的控件不会触发;
2. 在input任何属性改变时都会触发,使用时注意event.propertyName == 'value'过滤;
3. 修改了 input:checkbox 或者 input:radio 元素的选择中状态, checked 属性发生变化时触发。
4. 修改了 input:text 或者 textarea 元素的值,value 属性发生变化时触发。
5. 修改了 select 元素的选中项,selectedIndex 属性发生变化时触发。

oninput事件:
该事件是HTML5的标准事件,查看浏览器支持情况可以戳这里
需要注意的是:
1. 通过脚本改变value时不会触发;
2. 从浏览器的自动完成[autocomplete="on"]中选取时不会触发;
3. 适用元素textarea, input:text, input:password 和 input:search

综上所述要实现实时监听的需求:
如果在移动端(M端),可以直接使用oninput来解决;
如果在桌面端(PC端),可以使用oninput+onpropertychange兼容性处理。

但是这两个事件在IE9中都有个小BUG,那就是通过右键菜单中的剪切和删除命令删除内容的时候不会触发,而IE其他版本都是正常的,目前还没有很好的解决方案。不过 oninput & onpropertychange 仍然是监听输入框值变化的最佳方案。引用oninput event | input event中的描述:

The oninput event is buggy in Internet Explorer 9. It is not fired when characters are deleted from a text field through the user interface only when characters are inserted. Although the onpropertychange event is supported in Internet Explorer 9, but similarly to the oninput event, it is also buggy, it is not fired on deletion.
Since characters can be deleted in several ways (Backspace and Delete keys, CTRL + X, Cut and Delete command in context menu), there is no good solution to detect all changes. If characters are deleted by the Delete command of the context menu, the modification cannot be detected in JavaScript in Internet Explorer 9.

下面来看段代码来实现实时监听:

// This example shows how to use the oninput, onpropertychange and textInput events to detect when the contents of a textarea element is changed. Both the oninput and onpropertychange events are buggy in Internet Explorer 9, they are not fired when characters are deleted only when inserted.
var textarea = document.getElementById ("textarea");

if (textarea.addEventListener) {   
	// all browsers except IE before version 9
  textarea.addEventListener ("input", OnInput, false);
  // Google Chrome and  Safari
  textarea.addEventListener ("textInput", OnTextInput, false);
  // Internet Explorer from version 9
  textarea.addEventListener ("textinput", OnTextInput, false);
}

if (textarea.attachEvent) { 
	// Internet Explorer and Opera
  textarea.attachEvent ("onpropertychange", OnPropChanged);
}

// Google Chrome, Safari and Internet Explorer from version 9
function OnTextInput (event) {
  alert ("The following text has been entered: " + event.data);
}
// Firefox, Google Chrome, Opera, Safari from version 5, Internet Explorer from version 9
function OnInput (event) {
  alert ("The new content: " + event.target.value);
}
// Internet Explorer
function OnPropChanged (event) {
	// 使用event.propertyName 过滤
  if (event.propertyName.toLowerCase () == "value") {
    alert ("The new content: " + event.srcElement.value);
  }
}

参考链接:
input | oninput event[IE]
onpropertychange event | propertychange event
[JavaScript] oninput and onpropertychange Event Alternative
Using the oninput event handler with onkeyup/onkeydown as its fallback

下面是「FED实验室」的微信公众号二维码,欢迎扫描关注:

FED实验室

行文不易,如有帮助,欢迎打赏!

赞赏支持 喜欢 (2)
捐赠共勉
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(1)个小伙伴在吐槽