不使用jQuery的委托事件处理程序

3

我为您翻译了这个例子: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>

正如您所见,jQuery有一种很好的方法来做到这一点,第二个参数设置了“目标”和“this”,如果您单击外部div,即使事件处理程序在外部div上,也不会发生任何事情。

我如何在没有jQuery的情况下实现这一点?

那么,通过将事件处理程序放在内部,显然会“修复”问题,但我希望事件仍然保留在外部div上,但只针对内部,如何使其工作(而不是添加&& !(evt.target===outer))?

1个回答

3
基本的委托技术是:在内部设置可选择属性,然后将事件处理程序附加到外部,然后检查事件是否来自内部。
document.getElementById('outer').addEventListener('mousedown' function(outer_evt) {
    if (outer_evt.target.id == 'inner') {
        // I mousedowned on inner
    }
});

如果您将其他事件附加到outer包括附加到outer的任何祖先的事件),并且不希望在触发内部事件时触发它们,请使用outer_evt.stopImmediatePropagation()和/或outer_evt.stopPropagation()(分别)。
如果您想引用事件冒泡到的元素,那就是.currentTarget。(也就是说,在上面的例子中,outer_evt.currentTarget === document.getElementById('outer')
另请参见EventTarget.addEventListener()

.stopImmediatePropagation().stopPropagation()有什么区别?前者包含后者。而且我只有95%的把握你是指“附加到外部的处理程序”,而不是“附加到外部的事件”,对吗? - Robert Siemer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接