$(this)和event.target之间的区别?
我是jQuery新手,正在制作选项卡式面板,遵循JavaScript和jQuery教程:缺失手册 ,第一行是作者这样做的:
var target = $(this);
但我试图这样做
var target = evt.target;
我得到了这个错误:
Uncaught TypeError: Object http://localhost/tabbedPanels/#panel1 has no method 'attr'
当我将evt.target
改回$(this)
,它就像一个魅力。
我想知道$(this)
和evt.target
之间的区别是什么?
这是我的代码,以防您需要它:
index.html:
<!DOCTYPE html> <html> <head> <title>Tabbed Panel</title> <style> body { width : 100%; height: 100%; } #wrapper { margin : auto; width : 800px; } #tabsContainer { overflow: hidden; } #tabs { padding:0; margin:0; } #tabs li { float : left; list-style:none; } #tabs a { text-decoration:none; padding : 3px 5px; display : block; } #tabs a.active { background-color : grey; } #panelsContainer { clear: left; } #panel1 { color : blue; } #panel2 { color : yellow; } #panel3 { color: green; } #panel4 { color : black; } </style> <script type="text/javascript" src="jquery-1.8.0.min.js"></script> <script type="text/javascript" src="script.js"></script> </head> <body> <div id="wrapper"> <div id="tabsContainer"> <ul id="tabs"> <li><a href="#panel1">Panel1</a></li> <li><a href="#panel2">Panel2</a></li> <li><a href="#panel3">Panel3</a></li> <li><a href="#panel4">Panel4</a></li> </ul> </div> <div id="panelsContainer"> <div id="panel1" class="panel"> this is panel1 </div> <div id="panel2" class="panel"> this is panel2 </div> <div id="panel3" class="panel"> this is panel3 </div> <div id="panel4" class="panel"> this is panel4 </div> </div> </div> </body> </html>
script.js:
$(function(){ $("#tabs a").click(function(evt){ var target = evt.target, targetPanel = target.attr("href"); $(".panel").hide(); $("#tabs a.active").removeClass("active"); target.addClass("active").blur(); $(targetPanel).fadeIn(300); evt.preventDefault(); }); $("#tabs a:first").click(); })
$(this)
和event.target
之间是有区别的,而且是相当重要的一个。 虽然this
(或event.currentTarget
,见下文)总是引用监听器所附的DOM元素,但event.target
是被点击的实际DOM元素。 请记住,由于事件冒泡,如果你有
<div class="outer"> <div class="inner"></div> </div>
并将点击侦听器附加到外部div
$('.outer').click( handler );
那么当您单击外部div和内部div时(除非您有其他代码处理内部div上的事件并停止传播),将会调用该handler
。
在这种情况下,在handler
, this
(和event.currentTarget
)将引用.outer
DOM元素,并且event.target
将引用.inner
元素。
jQuery包装$(this)
只包装一个jQuery对象的DOM元素,所以你可以调用它的jQuery函数。 你可以用$(event.target)
做同样的事情。
还要注意,如果重新绑定这个上下文(例如,如果使用Backbone,它会自动完成),它将指向其他内容。 您始终可以从event.currentTarget
获取实际的DOM元素。
this
是正在处理事件的DOM元素(当前目标)的引用。 event.target
指的是发起事件的元素。 在这种情况下他们是一样的,往往可以,但他们并不总是如此。
您可以通过查看jQuery事件文档来了解这一点,但是总的来说:
event.currentTarget
事件冒泡阶段中的当前DOM元素。
event.delegateTarget
当前所谓的jQuery事件处理程序所在的元素。
event.relatedTarget
涉及事件的其他DOM元素(如果有的话)。
event.target
发起事件的DOM元素。
要使用jQuery获得所需的function,必须使用$(this)
或$(evt.target)
将其包装在jQuery对象中。
.attr()
方法仅适用于jQuery对象,不适用于DOM元素。 $(evt.target).attr('href')
或只是evt.target.href
会给你你想要的。
jQuery如何用“on”方法处理这个variables有一个很大的不同
$("outer DOM element").on('click',"inner DOM element",function(){ $(this) // refers to the "inner DOM element" })
如果你比较这个:
$("outer DOM element").click(function(){ $(this) // refers to the "outer DOM element" })
这里有跨浏览器的问题。
一个典型的非jQuery事件处理程序是这样的:
function doSomething(evt) { evt = evt || window.event; var target = evt.target || evt.srcElement; if (target.nodeType == 3) // defeat Safari bug target = target.parentNode; //do stuff here }
jQuery使evt
正常化,并使得目标在事件处理程序中可用,所以典型的jQuery事件处理程序将如下所示:
function doSomething(evt) { var $target = $(this); //do stuff here }
使用jQuery的标准化evt
和POJS目标的混合事件处理程序将是这样的:
function doSomething(evt) { var target = evt.target || evt.srcElement; if (target.nodeType == 3) // defeat Safari bug target = target.parentNode; //do stuff here }
当jQuery调用一个处理程序时,
this
关键字是对事件传递元素的引用; 对于直接绑定的事件,this
是事件附加的元素,对于委托事件,this
是一个元素匹配select器。 (请注意,如果事件已经从后代元素冒泡,this
可能不等于event.target
。)要从元素中创build一个jQuery对象,以便它可以用于jQuery方法,请使用$(this)。
如果我们有
<input type="button" class="btn" value ="btn1"> <input type="button" class="btn" value ="btn2"> <input type="button" class="btn" value ="btn3"> <div id="outer"> <input type="button" value ="OuterB" id ="OuterB"> <div id="inner"> <input type="button" class="btn" value ="InnerB" id ="InnerB"> </div> </div>
检查下面的输出:
<script> $(function(){ $(".btn").on("click",function(event){ console.log($(this)); console.log($(event.currentTarget)); console.log($(event.target)); }); $("#outer").on("click",function(event){ console.log($(this)); console.log($(event.currentTarget)); console.log($(event.target)); }) }) </script>
请注意,我使用$
来包装DOM元素,以创build一个jQuery对象,这是我们总是这样做。
你会发现,对于第一种情况, this
, event.currentTarget
, event.target
都被引用到相同的元素。
而在第二种情况下,当触发某个包装元素的事件委托时, event.target
将被引用到被触发元素,而this
和event.currentTarget
被引用到事件的传递位置。
对于this
和event.currentTarget
,根据http://api.jquery.com/event.currenttarget/ ,它们是完全一样的东西
在事件处理函数或对象方法中,访问“包含元素”属性的一种方法是使用特殊的this关键字。 这个关键字表示当前正在处理的函数或方法的所有者。 所以:
-
对于全局函数,这代表窗口。
-
对于对象方法,这表示对象实例。
-
而在事件处理程序中,这代表接收事件的元素。
例如:
<!DOCTYPE html> <html> <head> <script> function mouseDown() { alert(this); } </script> </head> <body> <p onmouseup="mouseDown();alert(this);">Hi</p> </body> </html>
渲染这个html之后的alert窗口的内容是:
object Window object HTMLParagraphElement
事件对象与所有事件相关联。 它具有提供“关于事件”信息的属性,例如在网页中单击鼠标的位置。
例如:
<!DOCTYPE html> <html> <head> <script> function mouseDown(event) { var theEvent = event ? event : window.event; var locString = "X = " + theEvent.screenX + " Y = " + theEvent.screenY; alert(event); alert(locString); } </script> </head> <body> <p onmouseup="mouseDown(event);">Hi</p> </body> </html>
渲染这个html之后的alert窗口的内容是:
object MouseEvent X = 982 Y = 329