Is there a difference between working a property of an element through the event.target vs working it directly?
I don't understand if there's any difference.
const btn = document.querySelector('#btn');
btn.addEventListener('click', function(e) {
console.log(e.target.value);
//vs
console.log(btn.value);
}
Is there a better practice when doing this?
Yes, there is an important difference. The event.target property tells you what element was involved with the creation of the event. For a "click", it's the element that was under the cursor when the "click" happened.
Thus if your HTML looked like:
<button><span>Text</span><img src="something.jpg"></button>
a click on the button content would trigger the event from either the <span> or the <img>, and one of those elements would be the target.
There's another event property, event.currentTarget, that is always a reference to the element to which the event handler is attached. That's probably what you want. Alternatively, if you bind handlers with .addEventListener(), then the value of this when the handler is invoked will be a reference to the same thing as currentTarget.
In your case you're selecting an element by ID. Your reference is the same as the target so there is no difference. A lot of time we use delegation so you might not have reference to the clicked element. Hence we use target from the event object.
Worth also to check target vs currentTarget
Related
When I was exploring StackOverflow's code, I get:
And I tried to get onclick event handler. There are the report:
> $0.onclick
< null
> $0.parentElement.onclick
< null
But $0.click() gives me some result (answer is upvoted).
How StackOverflow developers hid it and how to make it by hand, in pure JS?
While the .onclick property is one way to add a click event listener to elements, it's not the only way. Another way is via .addEventListener(). When an event listener is added to an element via .addEventListener(), the onclick attribute/property doesn't update to the event handler function. The .onclick property is only set on an element if you're using the onclick="" attribute or if the code has set the property elem.onclick = function() {...}, which nowdays isn't very often.
Chrome does provide you with a way to find the event handlers on different elements. When you're in your developer tools, you can select the element you're interested in, click "Event Listeners" in the right-hand pane, find the event you're intrested in, in this case that's the "click" event, and then look for your element:
Your element happens to have an event associated with it, but this might not always be the case. As the comments on your question have pointed out, you can sometimes run into cases where there is no click event handler on your specific element, but rather, it is added to a parent of that element. In this case, when you click on your element, the event propegates/"bubbles" up through the DOM, eventually reaching your parent element with the click event listener. The event handler on the parent can then see what element was originally clicked, and can then perform some actions based on that. This is known as event delegation, and is one of the reasons why you might not always find an event tied to your element even when looking in dev tools.
When a particular element is clicked, I want to call a function. When any of its children are clicked, I do not want to call the function.
I am not using jQuery.
Example:
I created a modal:
<div class="fullscreen-overlay">
<div class="card">
...
</div>
</div>
I want to call my closeModal() function when ".fullscreen-overlay" is clicked, but not when ".card" or any of its content are clicked.
jsfiddle:
https://jsfiddle.net/5kuwmf9s/
Research:
I could've sworn there was a CSS attribute for this, but after Googling and searching on SO for it, I can't find it / might've been imagining it. "pointer-events" stops it on the target element, not bubbling.
Theres another answer that suggests attaching an event handler to ALL children that catches their events and stops propagation - which seems unnecessary. My children are dynamic, and this will get complicated to keep attaching handlers.
You might have compared event's target and currentTarget
They would be equal only if the current element is the one that was the initial source of the event:
function handleClick(e){
if (e.target === e.currentTarget) {
alert('clicked!');
}
}
References:
https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget
https://developer.mozilla.org/en-US/docs/Web/API/Event/target
JSFiddle: https://jsfiddle.net/u78k4k6t/
try use an element and style it as your '.fullscreen-overlay' and bind event to this element
as the answer link shows
use event.target or event.srcElement
Is it possible to trigger an event on some object with a custom event object?
i.e.
$('#Element1').click(function(event){
console.log('Element1 clicked', event);
}
$('#Element2').click(function(event)
{ //handle click on one element
//optionally modify the event object
event.target=Something;
//Trigger the event handler(s) on some other element using modified event object
$('#Element1').click(event);
});
A bit of background:
In my instance Element2 is an almost identical clone of Element1 but with different position. When Element2 is clicked that click should be forwarded to Element1.
I already have code to identify the correct child of Element1 according to which child of Element2 was clicked but the click event handler on the child of element 1 requires the pageX and pageY properties to be set correctly and .click() omits these properties entirely.
It does not suffice in my example to do a deep clone and include the event handlers because the target property is incorrectly set.
One workaround in my instance would be for the cloned element to retain a reference to the original element (and for every child) and the handler to check for that reference, however, I would prefer a solution where the handler has no knowledge of the cloning process - not least because there are a LOT of handlers to modify!
I am not understand well your background logic, but you can try with trigger from jQuery. You can trigger event reusing the event object:
$('#Element1').click(function(event){
console.log('Element1 clicked with changed event: ' + event.something);
});
$('#Element2').click(function(event){
event.something = "Something";
$('#Element1').trigger(event);
});
You can try with .trigger() it accepts an event object as the argument
$('#Element1').trigger(event);
Demo: Fiddle
I'm a JS newbie - still learning. I'm looking for a solution similar to this example
for displaying the source link of an image in an alert using onclick. However, I want to apply it to any image on the page, and there are no ID's on any of the images. Perhaps this is an application of the mysterious 'this'? Can anyone help me? Thanks!
No, this has to do with delegate event listeners, and the way events spread across the DOM.
When you click on an element in the page, a click event is generated. For what it matters to your purposes, this event is fired on the element, and it's caught by the function you define with onclick.
But the event also "bubbles up" to the parent, and it's caught by the onclick function defined there, if any. And then to the parent of the parent, and so on.
What you have to do, now, is to catch the event on the root element, which is the document object itself, or maybe the document.body element if you still want to use onclick (which is deprecated).
The event object is passed to the onclick function and it contains the original element that fired the event:
document.body.onclick = function(e) {
var tgt = e.target || e.srcElement;
if (tgt.tagName === "IMG")
alert(tgt.src);
}
(The e.target || e.srcElement part is because in IE<9 the target property is called srcElement.) That's the way you define a delegate event listener. It's not defined on the <img> elements, as you can see, but on their common ancestor.
But since you can define just one click event listener in the traditional way, I'd strongly recommend to use something more modern like the addEventListener method, which lets you add multiple event listeners on the same element for the same event type:
document.body.addEventListener("click", function(e) {
...
});
In Internet Explorer <9 you'll have to use attachEvent, which is quite similar but not the same. For a cross-browser solution, use a common JS framework like jQuery, or Prototype, or whatever.
If I understand your question this is your solution,
var img = document.getElementsByTagName('img');
for(var i=0;i<img.length;i++){
alert(img[i].src);
}
is there a way to get the element? i.e:
$('#obj').hover(function() { },function() { /* here, i need to know the element that triggered this out event. */ });
thanks.
It's called ev.target
function (ev) {
var target = ev.target
// target triggered event
}
Of course you may not want the target but rather want the currentTarget
The currentTarget is the element the event handler is bound to.
As for the value of this in the callback. It's generally ev.currentTarget, jQuery uses that, the current DOM4 WD uses ev.target and the current DOM4 ED uses ev.currentTarget. I belief it's generally ev.currentTarget in legacy engines.
Note that if your not using jQuery but using the IE propitiatory event system then ev.srcElement is the equivelant of ev.target
in jQuery event binding, it passed you back an event object that you can access in your function, that object has the control in it, i think its targetElement or something like that ... so change your code to $('#obj').hover(function(ev) { }
and ev.targetElement should be what you're looking for.