oninput和onpropertychange以及其兼容处理

来源:互联网 发布:a站 b站 知乎 编辑:程序博客网 时间:2024/06/06 02:56

在我们鄙视ie浏览器的同时,也发现了ie浏览器在某些方面确实是领先于W3C的,比如监听属性改变的就是一个例子。

在传统意义上,处理表单输入框值的改变,需要监听onblur事件或者onchange事件,又或者直接监听输入框的键盘事件(onkeydownonkeypressonkeyup)、鼠标事件(onmousedownonmouseup)等。如果输入框的值被键盘或者鼠标剪切、粘贴、撤销、重做,或者是脚本动态改变的,都无法兼容监听值的变化。ie浏览器可以直接使用onpropertychange事件来完成,而其他浏览器则需要监听鼠标、键盘等等各种事件并处理数据后才能完成部分功能。索性的是HTML5已经为表单输入框单独增加了个方法oninput

1、onpropertychange

字面意思是能够监听property改变的事件,先看个基本例子:

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>onpropertychange</title>
  6. </head>
  7. <body>
  8. <input type="text" onpropertychange="listen(this)">
  9. <p id="p1"></p>
  10. <script>
  11. var oP1=document.getElementById('p1');
  12. function listen(obj){
  13. oP1.innerHTML+="input监听时间:"+new Date().getTime()+",其值被改变为:"+obj.value+"<br>";
  14. }
  15. </script>
  16. </body>
  17. </html>

如上,ie的onpropertychange不仅能监听正常的输入、剪切、粘贴,还能正确处理撤销操作(撤销操作不会额外触发增加一次事件,是真正意义上的撤销),如下图:

粘贴之后触发onpropertychange事件:

然后右键撤销操作:

很意外很惊喜的发现,事件触发了但没有额外增加一次。

同时onpropertychange能够监听到脚本改变输入框的值。

诚然,onpropertychange监听的是元素的property属性,并不只局限于value,也可以监听其他标准属性值,如:input的name值。

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>onpropertychange</title>
  6. </head>
  7. <body>
  8. <input id="input1" type="text" onpropertychange="listen(this)" name="1">
  9. <p id="p1"></p>
  10. <script>
  11. var oP1=document.getElementById('p1');
  12. function listen(obj){
  13. oP1.innerHTML+="input监听时间:"+new Date().getTime()+",其name值被改变为:"+obj.name+"<br>";
  14. }
  15. var xx=document.getElementById("input1");
  16. </script>
  17. </body>
  18. </html>

在控制台输入操作输入框的name属性:

如果改变的是非标准属性值呢?能不能监听?

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>onpropertychange</title>
  6. </head>
  7. <body>
  8. <input id="input1" type="text" onpropertychange="listen(this)">
  9. <p id="p1"></p>
  10. <script>
  11. var oP1=document.getElementById('p1');
  12. function listen(obj){
  13. oP1.innerHTML+="input监听时间:"+new Date().getTime()+",其myname的property值被改变为:"+obj.myname+"<br>";
  14. }
  15. var xx=document.getElementById("input1");
  16. </script>
  17. </body>
  18. </html>

仅仅改变输入框的myname的property值,却没有被监听到?!

如果换成attribute值,却可以被监听到:

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>onpropertychange</title>
  6. </head>
  7. <body>
  8. <input id="input1" type="text" onpropertychange="listen(this)">
  9. <p id="p1"></p>
  10. <script>
  11. var oP1=document.getElementById('p1');
  12. function listen(obj){
  13. oP1.innerHTML+="input监听时间:"+new Date().getTime()+",其myname的attribute值被改变为:"+obj.getAttribute("myname")+"<br>";
  14. }
  15. var xx=document.getElementById("input1");
  16. </script>
  17. </body>
  18. </html>

在控制台操作输入框的attribute:

关于property和attribute的延伸问题,参考:http://omiga.org/blog/archives/2055

2、oninput

字面意思是只能监听输入事件,看个基本例子:

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>oninput</title>
  6. </head>
  7. <body>
  8. <input id="input1" type="text" oninput="listen(this)">
  9. <p id="p1"></p>
  10. <script>
  11. var oP1=document.getElementById('p1');
  12. function listen(obj){
  13. oP1.innerHTML+="input监听时间:"+new Date().getTime()+",其value的property值被改变为:"+obj.value+"<br>";
  14. }
  15. var xx=document.getElementById("input1");
  16. </script>
  17. </body>
  18. </html>

监听的结果和ie的onpropertychange差不多(不作赘述):

但还有几处不同:

  • 撤销事件会额外增加一次触发。
  • 无法监听脚本改变的事件。
  • 更不能监听其他property属性和attribute属性。

3、兼容处理

需要做兼容的部分,就是onpropertychange和oninput不同的地方做兼容处理。在考虑到实际情况中,只需要对脚本动态改变输入框的值做监听就足够了。

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>oninput</title>
  6. </head>
  7. <body>
  8. <input id="input1" type="text" oninput="listen(this)">
  9. <p id="p1"></p>
  10. <script>
  11. var xx = document.getElementById("input1");
  12. var oP1 = document.getElementById('p1');
  13. var timer = 0;
  14. var value = "";
  15. function listen(obj) {
  16. if (timer) {
  17. clearInterval(timer);
  18. timer = 0;
  19. }
  20. oP1.innerHTML += "input监听时间:" + new Date().getTime() + ",其value的property值被改变为:" + obj.value + "<br>";
  21. value=obj.value;
  22. interval();
  23. }
  24. function interval() {
  25. timer = setInterval(function() {
  26. if (value != xx.value) {
  27. value = xx.value;
  28. oP1.innerHTML += "input监听时间:" + new Date().getTime() + ",其value的property值被改变为:" + xx.value + "<br>";
  29. }
  30. }, 100);
  31. }
  32. interval();
  33. </script>
  34. </body>
  35. </html>
1 0
原创粉丝点击