Delegated event handler without jQuery

喜欢而已 提交于 2019-12-20 03:08:47

问题


Made this example: https://jsfiddle.net/d8ak0edq/2/

document.getElementById('outer').oncontextmenu = function() { return false; };

outer = document.getElementById('outer');
outer.addEventListener('mousedown', foo);
function foo(evt) {
  if (evt.which === 1) {
    evt.target.style.backgroundColor = 'red';
  } else if (evt.which === 3) {
    evt.target.style.backgroundColor = 'blue';
  }
}
/*
$outer = $('#outer');
$outer.on('mousedown', 'div', foo);
function foo(evt) {
  if (evt.which === 1) {
    $(this).css('background-color', 'red');
  } else if (evt.which === 3) {
    $(this).css('background-color', 'blue');
  }
} */
#outer {
  border: 2px solid black;
  width: 300px;
  height: 300px;
}
#inner {
  position: relative;
  left: 25%;
  top: 25%;
  border: 2px solid black;
  width: 150px;
  height: 150px;
}
<!doctype html>
<html class="no-js" lang="">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Monoton">
        <link rel="manifest" href="site.webmanifest">
        <link rel="apple-touch-icon" href="icon.png">
        <!-- Place favicon.ico in the root directory -->
        <link rel="stylesheet" href="css/normalize.css">
        <link rel="stylesheet" href="css/main.css">
    </head>
    <body>
      <div id="outer">
        <div id="inner">
        
        </div>
      </div>


        <script src="js/vendor/modernizr-3.5.0.min.js"></script>
        <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
        <script>window.jQuery || document.write('<script src="js/vendor/jquery-3.2.1.min.js"><\/script>')</script>
        <script src="js/plugins.js"></script>
        <script src="js/main.js"></script>
    </body>
</html>

As you can see the jQuery has a nice way to do it, the 2nd parameter sets the 'target' and 'this' and if you click on the outer div nothing will happen even the event handler is on the outer div.

How do I make this without jQuery?

So by making the event handler on inner would obviously "fix" the problem, but I want that the event stays on the outer div but targets only inner, how to make this work (and not by adding && !(evt.target===outer))?


回答1:


The basic technique for delegation is: set a selectorable attribute on the inner, then attach event handler to the outer, then check for whether the event came from inner:

document.getElementById('outer').addEventListener('mousedown' function(outer_evt) {
    if (outer_evt.target.id == 'inner') {
        // I mousedowned on inner
    }
});

If you have other events attached to outer (this includes events attached to any ancestor of outer), and don't want them fired when you fire the inner event, use outer_evt.stopImmediatePropagation() and/or outer_evt.stopPropagation() (respectively).

If you want to refer to the element that the event bubbled up to, that's .currentTarget. (that is, above, outer_evt.currentTarget === document.getElementById('outer'))

See also EventTarget.addEventListener()



来源:https://stackoverflow.com/questions/48271532/delegated-event-handler-without-jquery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!