Разница между $(this) и event.target?
Я новичок в jQuery и делал панели с вкладками, следуя учебному пособию по JavaScript и jQuery: The Missing Manual. Когда автор делает это, появляется первая строка:
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();
})
7 ответов
Есть разница между $(this)
а также event.target
и довольно значительный. В то время как this
(или же event.currentTarget
см. ниже) всегда относится к элементу DOM, к которому был присоединен слушатель, event.target
это фактический элемент DOM, по которому щелкнули. Помните, что из-за пузыря события, если у вас есть
<div class="outer">
<div class="inner"></div>
</div>
и прикрепите прослушиватель кликов к внешнему div
$('.outer').click( handler );
тогда handler
будет вызван, когда вы щелкнете как по внешнему div, так и по внутреннему (если у вас нет другого кода, который обрабатывает событие на внутреннем div и останавливает распространение).
В этом примере, когда вы нажимаете внутри внутреннего div, то в handler
:
this
относится к.outer
Элемент DOM (потому что это объект, к которому был прикреплен обработчик)event.currentTarget
также относится к.outer
элемент (потому что это текущий целевой элемент, обрабатывающий событие)event.target
относится к.inner
элемент (это дает вам элемент, где произошло событие)
Оболочка JQuery $(this)
только оборачивает элемент DOM в объект jQuery, поэтому вы можете вызывать функции jQuery для него. Вы можете сделать то же самое с $(event.target)
,
Также обратите внимание, что если вы перепривязываете контекст this
(например, если вы используете Backbone, это делается автоматически), это будет указывать на что-то еще. Вы всегда можете получить фактический элемент DOM из event.currentTarget
,
this
является ссылкой на элемент DOM, для которого обрабатывается событие (текущая цель). event.target
относится к элементу, который инициировал событие. Они были одинаковыми в этом случае, и часто могут быть, но это не всегда так.
Вы можете получить представление об этом, просмотрев документацию по событиям jQuery, но вкратце:
event.currentTarget
Текущий элемент DOM в фазе всплытия событий.
event.delegateTarget
Элемент, к которому был прикреплен вызываемый в настоящее время обработчик события jQuery.
event.relatedTarget
Другой элемент DOM, участвующий в событии, если таковой имеется.
event.target
Элемент DOM, который инициировал событие.
Чтобы получить желаемую функциональность с помощью jQuery, вы должны обернуть его в объект jQuery, используя либо: $(this)
или же $(evt.target)
,
.attr()
Метод работает только с объектом jQuery, а не с элементом DOM. $(evt.target).attr('href')
или просто evt.target.href
даст вам то, что вы хотите.
Существует значительное различие в том, как jQuery обрабатывает переменную this методом on.
$("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"
})
http://api.jquery.com/on/ заявляет:
Когда jQuery вызывает обработчик,
this
ключевое слово - ссылка на элемент, куда доставляется событие; для напрямую связанных событийthis
элемент, к которому было прикреплено событие, и для делегированных событийthis
является селектором соответствия элемента (Обратите внимание, чтоthis
не может быть равенevent.target
если событие всплыло из элемента-потомка.)Чтобы создать объект 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, чтобы создать объект jQuery, как мы всегда делаем.
Вы найдете это для первого случая, this
,event.currentTarget
,event.target
все ссылки на один и тот же элемент.
В то время как во втором случае, когда делегат события для некоторого обернутого элемента сработал, event.target
будет ссылаться на триггерный элемент, в то время как this
а также event.currentTarget
ссылки на то, где событие доставлено.
За this
а также event.currentTarget
по словам http://api.jquery.com/event.currenttarget/ это одно и то же
Здесь есть кросс-браузерные проблемы.
Типичный не-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
и делает цель доступной как this
в обработчиках событий, поэтому типичный обработчик событий 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
}
'this' относится к объекту DOM, к которому был присоединен прослушиватель событий. ' event.target' относится к объекту DOM, для которого сработал прослушиватель событий. Возникает естественный вопрос, почему прослушиватель событий срабатывает для других объектов DOM. Это связано с тем, что прослушиватель событий присоединил родительские триггеры и к дочернему объекту.
В функции-обработчике события или методе объекта одним из способов доступа к свойствам "содержащего элемента" является использование специального ключевого слова this. Ключевое слово this представляет владельца функции или метода, обрабатываемого в данный момент. Так:
Для глобальной функции это представляет окно.
Для метода объекта это представляет экземпляр объекта.
И в обработчике событий это представляет элемент, который получил событие.
Например:
<!DOCTYPE html>
<html>
<head>
<script>
function mouseDown() {
alert(this);
}
</script>
</head>
<body>
<p onmouseup="mouseDown();alert(this);">Hi</p>
</body>
</html>
Содержимое окон оповещения после рендеринга этого HTML соответственно:
object Window
object HTMLParagraphElement
Объект Event связан со всеми событиями. У него есть свойства, которые предоставляют информацию "о событии", например, местоположение щелчка мыши на веб-странице.
Например:
<!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 соответственно:
object MouseEvent
X = 982 Y = 329