jQuery: How to stop propagation of a bound function not the entire event?

后端 未结 2 1140
清歌不尽
清歌不尽 2021-02-11 05:38

I have a click function bound to many elements. It is possible that sometimes these elements may sit within one another. So, the click event is bound to a child and also bound

2条回答
  •  梦毁少年i
    2021-02-11 06:21

    The suggested solution

    evt.target == evt.currentTarget
    

    is nice, but there are cases where it does not help.

    Example: A (suckerfish-style) menu structure with nested ul/li lists.
    The mousemove event comes from a link inside a list item, which is a child of an ul-list, which is again a child of another list item. Typical for a html menu structure with submenus.
    The evt.target would be the link tag, but we are interested in the mousemove on the list item.
    Even worse: The link tag could contain span or img tags or other nested stuff. Then evt.target would be this span or img.

    What seems to work here is to catch the event on a parent / root item, and then check the parents of evt.target.

    Like this (with 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. (?)
      }
    });
    

    Maybe some of this could be abbreviated with jQuery like $(evt.target).parents().is($menu), but I did not get this to work. Also, I would guess that this explicit loop with element.tagName is faster.

提交回复
热议问题