【问题标题】:Fire onblur event before onchange event在 onchange 事件之前触发 onblur 事件
【发布时间】:2013-08-15 10:24:09
【问题描述】:

我有一个包含多个文本输入字段的大型表单。本质上,我需要处理 所有字段onchange 事件和 一些 字段的 onblur 事件。当对字段进行更改并且该字段失去焦点时,两个事件都会触发(这是正确的行为)。唯一的问题是我想处理onblur 在我处理 onchange 事件之前的事件。

在 ie 和 Firefox 中进行一些测试后,似乎默认行为是在 onblur 之前触发 onchange 事件。我一直在使用下面的代码作为测试...

<html>

<body >
    <input type="text" value="here is a text field" onchange="console.log('Change Event!')" onblur="console.log('Blur Event!')" >

</body>
</html>

这让我想到了我的问题:

  1. 似乎这种行为在浏览器中是一致的。为什么onchange会先火?

  2. 由于我无法为每个输入元素处理 onblur 事件,有没有办法让 onblur 在处理 onchange 事件之前触发?

【问题讨论】:

  • 您的标签中有jQuery。你在用吗?如果是这样,您可以通过检查处理程序中的event.type,以您想要的任何顺序处理事件。
  • @DevlshOne - 但是你不能改变他们被解雇的顺序..
  • @DevlshOne 我在我的实际项目中使用它,所以它可以用于解决方案。
  • 不,你不能,但你可以按照你想要的任何顺序处理它们。
  • 在 onchange 调用中使用 setTimeout 调用来延迟执行。

标签: javascript jquery html dom javascript-events


【解决方案1】:
  1. onchange 首先触发的原因是,一旦元素失去焦点(即“模糊”),更改通常是完整的(我说通常是因为脚本仍然可以在没有用户交互的情况下更改元素)。

  2. 对于那些需要首先处理onblur 的元素,您可以禁用onchange 处理程序并从onblur 处理程序触发onchange(甚至是自定义事件)。这将确保正确的顺序,即使它是更多的工作。要检测变化,您可以为该字段使用状态变量。

不过,总而言之,对这种同步性的需求表明,您用来解决所要解决的任何问题的方法可能需要更多的工作,即使有时无法避免。如果您确定这是唯一的方法,请尝试以下方法之一!

编辑:为了详细说明最后一点,您必须遵循有关事件模型的一些假设。您是否假设每个change 事件后跟一个blur 并且未处理,或者您是否希望处理每个change 但后面跟一个blur 的事件在onblur 执行任何操作之后得到进一步处理跟他们?在任何情况下,如果您想强制执行处理程序需要访问公共资源(全局变量、属性等)的顺序。您可能还想使用其他事件类型吗? (input?)。最后,此链接包含有关 Mozilla 浏览器的 change 事件的一些详细信息: https://developer.mozilla.org/en-US/docs/Web/Reference/Events/change。 第三个“子弹”解决了事件顺序问题。

【讨论】:

  • +1:“对这种同步性的需求表明您正在使用的方法......可能需要更多工作”
  • 如果我只处理那些选择元素的 onblur 事件,我将失去知道该字段是否已更改的能力......因此 onchange 处理程序。为每个字段创建状态变量并不是很简单
  • @Joel 由于onchange 出现在之前,您可以在元素上设置数据属性以指示在onchange 处理程序中的值已更改,然后在@ 中读取并清除此属性987654336@handler,照着办。
  • 我刚刚添加了一条评论来准确解决这个问题。您可以将状态保存在单独的变量中。一种更简洁但更乏味的方法是将onblur 事件的处理分成两部分:第二部分由onchange 触发,然后返回到onchange 处理程序的后半部分(这是可能而且矫枉过正)。
【解决方案2】:

这有点小技巧,但它似乎在大多数浏览器上都能解决问题:

<input type="text" value="Text Input" onchange="setTimeout(function(){console.log('Change Event!')}, 0);" onblur="console.log('Blur Event!');" />

你可以在这里看到它的作用:http://jsfiddle.net/XpPhE/

这里是setTimeout(function, 0)技巧的一些背景信息:http://javascript.info/tutorial/events-and-timing-depth

希望有帮助:)

【讨论】:

  • 我不确定这有多可靠。这听起来不像规范会保证事件处理程序会在之前使用setTimeout安排回调,所以你可能只是依赖那里的实现细节。
猜你喜欢
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多