选择除div以外的所有元素不适用于jQuery

时间:2018-11-27 16:47:31

标签: jquery jquery-selectors jquery-events mouseup jquery-trigger

我正在尝试选择文档中除#private_chat_menu元素之外的所有元素,并将mouseup触发函数附加到它们。但是,无论我是否单击#private_chat_menu元素内的选择框,它都会运行该函数。这是代码:

<script>
$("*:not(#private_chat_menu > *)", "body").mouseup(function(e)
{
    var chat_user_container = $('#private_chat_menu');
    var chat_container = $('#chat-wrapper');

    if (chat_container.css("visibility") == 'visible' && chat_user_container.is(':visible'))
    {
        chat_user_container.hide();
    }
});
</script>

<div id="chat-wrapper">
   <div id="private_chat_menu">
      <select id="chat_user_select" name="chat_user_select">
         <option value="">Select Assigned User</option>
         <option value="1">...</option>
         <option value="2">...</option>
      </select>
   </div>
</div>

JSFiddle:http://jsfiddle.net/q0ky2f56/

2 个答案:

答案 0 :(得分:0)

鉴于您的要求,如果将单个事件处理程序附加到document并询问引发该事件的元素,则该方法会更好(并且逻辑更简单)。如果它是#private_chat_menu或它的孩子,请不要执行任何操作。像这样:

var $chat_user_container = $('#private_chat_menu');
var $chat_container = $('#chat-wrapper');

$(document).on('mouseup', function(e) {
  var $target = $(e.target);
  if ($target.is($chat_user_container) || $target.closest($chat_user_container).length)
    return;

  if ($chat_container.is(':visible') && $chat_user_container.is(':visible')) {
    $chat_user_container.hide();
  }
});

答案 1 :(得分:0)

首先,通过.on()使用事件委托。与将事件绑定到多个元素相比,它更清洁,更易于维护。使用委派,我们将事件绑定一次(绑定到顶级元素,例如body),然后在事件运行时,确定是否要针对触发事件的目标元素继续进行该事件。

我们可以通过将选择器作为第二个参数传递给on()来做到这一点,但是在您的情况下,由于关于事件是否应该运行的逻辑很重要,因此对此进行测试可能会更容易在回调中。

关键是要排除#private_chat_menu及其子代/后代。

$('body').on('mouseup', '*', function(e) {
    if ($(this).closest('#private_chat_menu').length) return;
    //safe to continue...
});

closest()说:“当前元素或任何父元素/祖先元素是否与传递的选择器匹配?”如果是,我们知道我们不应该允许事件运行。