div上的focusout事件没有按预期工作

时间:2014-02-19 06:36:59

标签: javascript jquery html

我有以下jQuery代码:

$("#contact-form-applet").on("focusout",".dc2-ltfc", {ctx:this},function(event) {
    var curRowDiv = $(this);
    var rowObject = {};
    curRowDiv.find("input, textarea").each(function(e){
        rowObject[ $(this).attr("aria-label") ] = $(this).val();
    });
    console.log(rowObject);
}); 

问题是,每当一个字段失去一个焦点(字段标签输出)而不是完全失去焦点的div时,就会触发代码。

以下JS Fiddle link证明了这个问题。

我想仅在特定行div丢失焦点时才触发代码,这样我就可以触发一次更新,而不是每次更新一行中的字段。

2 个答案:

答案 0 :(得分:0)

jquery documentation说:

  

当焦点输出事件或任何元素发送到元素时   在里面,失去了焦点。

因此,每当任何一个子元素失去焦点时,focusout事件就会触发。或者,您可以使用body的{​​{1}}和keyup事件通过检查click元素来解决此问题:

closest

以下是展示解决方案的fiddler

答案 1 :(得分:0)

聚会迟到了,但其他人可能会觉得它很有用。我的解决方案有点骇人听闻,但它是确定性的。它依赖于 JS 引擎如何在其单个执行线程上调度异步进程。解决方案是在 Angular 中用于多行数据,我想知道用户是否访问了同一行中的不同字段(不触发保存)或将行留在不同行或其他任何地方(触发保存)。 div(行)用行索引标识,但您可以根据用例使用任何标签来标识 div。

在div中添加focusin和focusout事件处理程序(显示一行数据):

<div class="hover-row row"
    *ngFor="let lineItem of line_items; let i = index"
    (focusout)="onFocusOut(i)" (focusin)="onFocusIn(i)">

然后创建这些事件处理函数:

  onFocusOut(index) {
    console.log('row focus out');
    this.newAccessedIndex = -1; 
    setTimeout(() => this.saveLineItem(index), 0);
  }

  onFocusIn(index) {
    console.log('row focus in');
    this.newAccessedIndex = index;
  }

  saveLineItem(index) {
    if (index == this.newAccessedIndex) {
      console.log('stayed within row -> no save');
    } else {
      console.log('left row -> save');
    }
  }

这个想法是,当在行中留下输入字段时,会在 div 上触发 focusout。如果在同一行中访问不同的输入字段,则会为 div 触发 focusin。在 focusout 中我们重置最后访问行的索引(标签),在 focusin 中我们设置索引。在 focusout 中,saveLineItem 在不同的执行线程上被调用,因此当从一个输入字段访问一行中的 Tab 键时,我们会得到这些控制台日志:

row focus out
row focus in
stayed within row -> no save