【问题标题】:jQuery: focusout triggering before onclick for Ajax suggestionjQuery:针对 Ajax 建议的 onclick 之前触发 focusout
【发布时间】:2013-11-18 17:32:13
【问题描述】:

我正在构建一个网页,我需要能够通过下拉菜单选择 1-9 名成员,然后提供许多输入字段来输入他们的姓名。每个名称字段在其下方都有一个“建议”div,其中填充了 ajax-fed 成员列表。该列表中的每个项目都有一个与之关联的“onclick='setMember(a, b, c)'”字段。一旦输入字段失去焦点,我们就会验证(使用 ajax)输入用户名是否正好返回 1 个数据库条目,并将该字段设置为该条目的文本,并将关联的隐藏 memberId 字段设置为该条目的 ID。

问题是:当我单击建议框中的成员名称时,会触发失去焦点,它会尝试验证具有多个匹配项的名称,从而将其清除。我确实希望它在无效时清除,但我不希望它在单击建议框名称之前清除。

例子:

在上面的示例中,如果在失去焦点时建议列表中只有一个名字,Paul Smith 会很好地填充,但如果我尝试在建议区域单击 Raphael 的名字(即:单击灰色 div),它会首先清除输入字段。

这里是 javascript,为简洁起见:

function memberList() {
    var count = document.getElementById('numMembers').value;
    var current = document.getElementById('listMembers').childNodes.length;
    if(count >= current) {
  for(var i=current; i<=count; i++) {
    var memberForm = document.createElement('div');
    memberForm.setAttribute('id', 'member'+i);
    var memberInput = document.createElement('input');
    memberInput.setAttribute('name', 'memberName'+i);
    memberInput.setAttribute('id', 'memberName'+i);
    memberInput.setAttribute('type', 'text');
    memberInput.setAttribute('class', 'ajax-member-load');
    memberInput.setAttribute('value', '');
    memberForm.appendChild(memberInput);
    // two other fields (the ones next to the member name) removed for brevity

    document.getElementById('listMembers').appendChild(memberForm);

  }
}
else if(count < current) {
   for(var i=(current-1); i>count; i--) {
       document.getElementById('listMembers').removeChild(document.getElementById('listMembers').lastChild);
   }
}

jQuery('.ajax-member-load').each(function() {
var num = this.id.replace( /^\D+/g, '');

// Update suggestion list on key release
jQuery(this).keyup(function(event) {
    update(num);
});

// Check for only one suggestion and either populate it or clear it
jQuery(this).focusout(function(event) {
  var number = this.id.replace( /^\D+/g, '');
  memberCheck(number);
  jQuery('#member'+number+'suggestions').html("");
});
  });

}

    // Looks up suggestions according to the partially input member name
function update(memberNumber) {

  // AJAX code here, removed for brevity

  self.xmlHttpReq.onreadystatechange = function() {
    if (self.xmlHttpReq.readyState == 4) {
              document.getElementById('member'+memberNumber+'suggestions').innerHTML = self.xmlHttpReq.responseText;
    }
  }
} 

// Looks up the member by name, via ajax
// if exactly 1 match, it fills in the name and id
// otherwise the name comes back blank and the id is 0
function memberCheck(number) {

   // AJAX code here, removed for brevity

    if (self.xmlHttpReq.readyState == 4) {
          var jsonResponse = JSON.parse(self.xmlHttpReq.responseText);
          jQuery("#member"+number+"id").val(jsonResponse.id);
          jQuery('#memberName'+number).val(jsonResponse.name);
    }
  }
}
function setMember(memberId, name, listNumber) {
   jQuery("#memberName"+listNumber).val(name);
   jQuery("#member"+listNumber+"id").val(memberId);
   jQuery("#member"+listNumber+"suggestions").html("");
}

// Generate members form
memberList();

建议 div(现在在点击和触发之前被删除)看起来像这样:

<div onclick='setMember(123, "Raphael Jordan", 2)'>Raphael Jordan</div>
<div onclick='setMember(450, "Chris Raptson", 2)'>Chris Raptson</div>

有没有人知道如何解决这个优先级问题?我确定我不会是第一个遇到这个问题的人,但我不知道要搜索什么才能找到类似的问题。

谢谢!

【问题讨论】:

    标签: javascript jquery ajax triggers


    【解决方案1】:

    如果您使用 mousedown 而不是单击建议绑定,它将在输入模糊之前发生。 JSFiddle.

    <input type="text" />
    <a href="#">Click</a>
    
    $('input').on('blur', function(e) {
       console.log(e);
    });
    
    $('a').on('mousedown', function(e) {
       console.log(e); 
    });
    

    或者更具体地针对您的情况:

    <div onmousedown='setMember(123, "Raphael Jordan", 2)'>Raphael Jordan</div>
    

    【讨论】:

    • 简单又好用,非常感谢!由于我对高级 Javascript 和 jQuery 还很陌生,您知道任何“功能优先级”列表吗?例如,有一个参考说明 onmousedown>focusout=blur>onclick 会有所帮助。
    • 我不知道所有事件类型和场景的任何全局列表以及触发事件的顺序。我知道按鼠标/键盘事件的顺序查找引用相当容易,但这些引用通常(曾经?)不涉及焦点状态的关系。
    【解决方案2】:

    使用 onmousedown 代替 onclick 将调用 focusout 事件,但在 onmousedown 事件处理程序中,您可以使用 event.preventDefault() 来避免失去焦点。这对于您不想在单击眼睛图标以显示/隐藏密码时放松对输入字段的关注的密码字段很有用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多