我有以下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丢失焦点时才触发代码,这样我就可以触发一次更新,而不是每次更新一行中的字段。
答案 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