jQuery: как остановить распространение связанной функции, а не всего события? - PullRequest
2 голосов
/ 05 июня 2010

У меня есть функция щелчка, связанная со многими элементами. Возможно, что иногда эти элементы могут находиться внутри друг друга. Таким образом, событие click привязано к дочернему элементу, а также к его родительскому элементу. Метод зависит от элемента, по которому щелкнули. Естественно, из-за всплесков событий сначала запускается событие ребенка, а затем родителей. Я не могу вызвать их обоих одновременно, потому что событие родителей перезаписывает событие ребенка. Так что я мог бы использовать event.stopPropagation (), чтобы событие получал только первый нажатый элемент. Проблема в том, что к этому элементу также прикреплены другие события щелчка, например, я использую перетаскиваемый jQuery для этих элементов. Если я остановлю распространение события click, перетаскиваемый элемент не будет работать, и следующие события click не будут вызваны.

Итак, мой вопрос: есть ли способ остановить всплывающее событие для метода, который будет вызывать событие, а не для всего события?


Блестящий Джон, но вот в чем проблема.

<div id="Elm1"><!-- relative -->
 <div class="Elmchildren"></div><!-- absolute-->
 <div class="Elmchildren"></div><!-- absolute-->
 <div class="Elmchildren"></div><!-- absolute-->

 <div id="Elm2"><!-- relative -->
  <div class="Elmchildren"></div><!-- absolute-->
  <div class="Elmchildren"></div><!-- absolute-->
  <div class="Elmchildren"></div><!-- absolute-->
 </div>

</div>

событие клика связано с # Elm1 и # Elm2. .Elmchildren ширина и высота 100%. Таким образом, они на самом деле являются текущими целями.

Ответы [ 2 ]

4 голосов
/ 05 июня 2010

попробуйте что-нибудь подобное

$(mySelector).click(function(evt) {
  if (evt.target == evt.currentTarget) {
      ///run your code.  The if statment will only run this click event on the target element
      ///all other click events will still run.
  }
});
1 голос
/ 01 августа 2011

Предлагаемое решение

evt.target == evt.currentTarget

это хорошо, но есть случаи, когда это не помогает.

Пример: структура меню в стиле suckerfish со вложенными списками ul / li.
Событие mousemove происходит от ссылки внутри элемента списка, который является дочерним элементом ul-list, который снова является дочерним элементом другого элемента списка. Типично для html-структуры меню с подменю.
Evt.target будет тегом ссылки, но нас интересует перемещение мыши по элементу списка.
Еще хуже: тег link может содержать теги span или img или другие вложенные элементы. Тогда evt.target будет этот промежуток или img.

Кажется, что здесь работает, чтобы перехватить событие на родительском / корневом элементе, а затем проверить родителей evt.target.

Как это (с JQuery),

var $menu = $('div#menu');
$('body').mousemove(function(evt){
  var element = evt.target;
  // find the deepest list item that was affected by this mouseover event.
  var list_item;
  var in_menu = false;
  while (element) {
    if (element == $menu[0]) {
      in_menu = true;
      break;
    }
    else if (!list_item && element.tagName == 'LI') {
      // we found a list item, but we are not sure if we are inside the menu tree.
      list_item = element;
    }
  }
  // do something with the result.
  if (!in_menu) {
        .. // close all submenus
  }
  if (list_item) {
    .. // open the submenu for this list item.
  }
  else {
    // mouse in menu, but not hovering an item.
    // leave the submenus open. (?)
  }
});

Возможно, что-то из этого может быть сокращено с помощью jQuery, например, $ (evt.target) .parents (). Is ($ menu), но я не смог заставить это работать Кроме того, я предполагаю, что этот явный цикл с element.tagName быстрее.

...