【问题标题】:Issue with JavaScript/jQuery event ordering?JavaScript/jQuery 事件排序问题?
【发布时间】:2015-04-12 17:12:56
【问题描述】:

我遇到了事件未按预期顺序触发的问题。我在输入元素上有一个用于聚焦和聚焦的事件。 .focus() 显示一些内容, .focusout() 隐藏它。我希望能够对使用 .focus() 显示的一些数据进行 .click(),但是当我单击它时,首先要触发的是 .focusout() 事件处理程序,并且对于使用 .click() 事件处理程序隐藏内容的操作出于某种原因。

这是我的事件监听器:

$('#content').click(function(evt) {
    alert('Yay');
});

$('input').focus(function() {
    $('#content').show();
});

$('input').focusout(function() {
    $('#content').hide();
});

如果其中任何一个令人困惑,您可以在此 jsfiddle 中查看确切的行为。单击输入框时,会显示红色框。但是,如果您随后尝试激活红色框上的单击侦听器,则 .focusout() 优先并隐藏内容,并且不会发生 .click() 事件。

期望的行为:点击输入,显示内容,点击内容,触发内容点击监听器。

【问题讨论】:

  • 它会在被点击之前隐藏,因此不会触发点击事件,因为它没有被点击
  • 不确定我确切地知道你想要什么,但这是否接近jsfiddle.net/j08691/etckaehL
  • @j08691 或多或少。你解决了这个问题,但我更好奇为什么会发生这种情况。我认为事件是先进先出的。
  • @ShaifulIslam 据我了解,这些事件发生在 FIFO 队列中。由于我首先定义了点击事件,所以我假设它会被首先调用。
  • 您可以使用@guest271314 解决方案来隐藏内容,以便触发点击事件

标签: javascript jquery events listener


【解决方案1】:

更新-> 这就是你想要的:

$("#content").click(function (evt)
{
    if (evt.target == document.getElementById("content"))
    {  alert("Yay");
       $('#content').show();
       $('input').focus();
    }
});


$('input').focus(function() {
    $('#content').show();
});

$('input').focusout(function() {
      setTimeout(function(){ $('#content').hide(); }, 100);    
});

这行得通。

【讨论】:

  • 如果你点击它之外的任何地方,它不会隐藏内容div。
  • 目的不是在点击内容时隐藏内容。内容应该根据输入是否被聚焦来显示/隐藏,并且仍然是可点击的。
【解决方案2】:

编辑、更新

试试

$('#content').click(function(evt) {
    alert('Yay'); 
});

$('input').focus(function() {
    $('#content').show();
});

$('input').on("focusout", function() {
    $('#content').delay(100).hide(1);
});

$('#content').click(function(evt) {
    alert('Yay'); 
});

$('input').focus(function() {
    $('#content').show();
});

$('input').on("focusout", function() {
    $('#content').delay(100).hide(1);
});
#content {
    height: 200px;
    width: 200px;
    display: none;
}

#content {
    background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content">    
</div>

<input type="search">

【讨论】:

  • 如果你点击它之外的任何地方,它不会隐藏内容div。
  • 是的,这解决了问题。我想我并不是真的在寻找一个直接的解决方案(这很好,不要误会我的意思),而是要了解正在发生的事情以及为什么事件不是 FIFO。
  • @bawjensen 见developer.mozilla.org/en-US/docs/Web/Events/focusout “一个元素即将失去焦点(气泡)。” developer.mozilla.org/en-US/docs/Web/Events/click “一个指向设备按钮已在元素上被按下并释放。"
  • @bawjensen focusout 似乎在 指针设备click event 已“释放”之前触发
  • @guest271314 这正是我正在寻找的解释。谢谢!
【解决方案3】:

试试

$('#content').click(function(evt) {
  clearTimeout($(this).data('focusTimer'))
});

$(document).click(function(e) {
  if ($(e.target).closest('#content').length == 0) {
    $('#content').hide();
  }
})

$('input').focus(function() {
  $('#content').show();
});

$('input').focusout(function() {
  var timer = setTimeout(function() {
    $('#content').hide();
  }, 500)
  $('#content').data('focusTimer', timer);
});
#content {
  height: 200px;
  width: 200px;
  display: none;
}
#content {
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="content"></div>
<input type="search">

【讨论】:

    猜你喜欢
    • 2011-03-25
    • 2014-07-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    相关资源
    最近更新 更多