事件监听的this:「这个」到底是哪一个?

欧阳克是谁杀的?

这个this是谁?要看凶手是谁而定!

前面有提到,这个e是在当事件发生时,事件处理器自动建立的「事件物件」,里面纪录了跟事件有关系的资讯,并把这个e当参数传入事件发生时设定要执行的函式。

如果我们想要印出,滑鼠所点击的元素的标签名称,可以这样写:

element.addEventListener('click', function (e){
	console.log(e.target.tagName);
},false)

「e.target」就是「触发事件的元素」。在这种状况下,我们可以使用「this」来取代 「e.target」。

当我们选取DOM元素来做事件监听的时候,this会指向那个DOM元素。以下这段程序,滑鼠点击之後,字体会变成红色的。

<div id="sword">
  <ul class="fiveHero">
    <li class="firstHero">1 东邪</li>
    <li class="secondHero">2 西毒</li>
    <li class="thirdHero">3 南帝</li>
    <li class="fifthHero">4 北丐</li>
    <li class="lastHero">5 中神通</li>
  </ul>
</div>
var elements = document.getElementsByTagName('li');

function changeColor(e) {
	console.log(e.target);
  e.target.style.color = 'red';
}

for (var i = 0; i < elements.length; i++) {
  elements[i].addEventListener('click', changeColor, false);
}

我们用「this」来取代「e.target」,跟上面那个JavaScript程序区块呈现一样的效果。

var elements = document.getElementsByTagName('li');
//没有用e当function的参数
function changeColor() {
	console.log(this);
  this.style.color = 'red';
}

for (var i = 0; i < elements.length; i++) {
  elements[i].addEventListener('click', changeColor, false);
}

但是当「事件监听」是被其他元素的事件所触发的时候,「this」就不等於「e.target」了。来看看下面的例子:

<div class="outer">
    <div class="inner"></div>
</div>
var inner = document.querySelector('.inner')
var outer =document.querySelector('.outer');
inner.addEventListener('click', function(e) {
  console.log(e.target.className,1)
  console.log(this.className,1)
},false)

outer.addEventListener('click', function(e){
    console.log(e.target.className,2)
    console.log(this.className,2)
},false)

点击黄色区块後,出来的结果是:

"inner" 1  //黄色区块所触发的事件,e.targer = 触发事件的元素
"inner" 1  //黄色区块所触发的事件,e.target = this = 触发事件的元素
"inner" 2  //黄色区块事件冒泡所触发的事件 , e.target = 触发事件的元素
"outer" 2  //黄色区块事件冒泡触发红色区块的事件, this = 被事件冒泡所触发的元素,而非e.target

在这个例子中,outer.addEventListener() 是被 inner.addEventListener() 的事件冒泡所触发,e.target为触发事件的元素,真正的凶手当然就是inner。而outer.addEventListener()的this却是指向outer,它是被事件冒泡所触发的元素,也就是e.currentTarget,也就是被害者,被inner害的。

在没有事件冒泡影响的情况下,e.target = this,凶手与被害者是同一人,也就是自作自受。

当元素的事件是被事件冒泡所触发的时候:

e.target 是凶手,郎是伊抬ㄟ!

e.currentTarget 就是被害者!this 就是 e.currentTarget!也就是被事件冒泡影响所触发的元素。

欧阳克是被杨康杀的!

咦!


<<:  D-17 路由 ? Routing

>>:  Day13-Webhook 实作(二)LINEBot 之 Echo bot

将Word(Excel)内容汇出成SVG

因为前阵子发表的研讨会文章被转期刊,所以这几天都在忙着重写文章,遇到一个大家都觉得很烦排版的问题,这...

进击的软件工程师之路-软件战斗营 第六周

学习进度 游戏专题 Delay 地图编辑器使用 (自学)人物移动&转向 (自学)子弹360度...

Day 20:非 GUI 类工具之 juce::Analytics

为简化使用者行为采集,JUCE 提供了 juce::Analytics 以及相关介面,让开发者依需求...

Day 28 重构也是需要时间的不是吗?

重构也是需要时间的不是吗? 的确,重构也是需要额外时间的,但这应该是我们专业的一部份。一个好的重构时...

Day2 理解 golang slice 用法及原理 II

续上篇 Day1 理解 golang slice 用法及原理 I 什麽是 slice 是的容量 (c...