IE上的onchange事件和程序输入值更改冲突

Mar*_*nez 11 html javascript internet-explorer

我注意到,在不同版本的Internet Explorer中,当输入的值被js函数更改时,不会捕获onchange事件,这种行为在其他浏览器(如Mozilla或Chrome)中不会发生.

稍微调查一下,我发现onchange当js改变值时,IE 中的正确操作无法保证:

function onchangeRequest(){
  console.log('onchange fired');
}

function changeValue (input){
  input.value +=  "hello"
}
Run Code Online (Sandbox Code Playgroud)
<h4> focus lost doesnt invoke onchangeRequest() </h4>

<input id="valueInput"  onkeyup="changeValue(this);" onchange="onchangeRequest();" />

<h4> focus lost invokes onchangeRequest() </h4>

<input id="valueInput" onchange="onchangeRequest();" />
Run Code Online (Sandbox Code Playgroud)

我还没有找到令人信服的解释,说明为什么IE无法正确解决这些问题.这是我们必须处理的"已知错误"吗?是否有任何官方参考声称IE不保证onchange事件的正确行为?

Mar*_*nez 8

我发现多年来微软遵循的策略是在浏览器中没有遵循W3C标准,但根据IE自己的规范行为是正确的:

当以编程方式更改选定对象的选定选项时,不会触发 onchange事件.

参考:MSDN - onchange事件

解决此问题并使您的解决方案跨浏览器的可能解决方法是:

  • onfocus:将输入值保存在expando属性上
  • onblur:调用js函数,将旧值与当前值进行比较.

在我的现实生活场景中,我需要在输入值改变时触发ajax动作,因此使用onblur事件而不比较更改将导致对后端的大量不必要的调用.

这是一个例子:

function onchangeRequest(input){
  if(input.value != input.oldValue){
      console.log('value changed: do ajax request');
  }else{
      console.log('value didnt change');
  }
}

function changeValue (input){
     input.value +=  "add"
 }
Run Code Online (Sandbox Code Playgroud)
<input id="valueInput" onkeyup="changeValue(this);" onfocus="this.oldValue = this.value;" onblur="onchangeRequest(this);" />
Run Code Online (Sandbox Code Playgroud)