How do I locate the right origin of an event in a complex object via Javascript?

Asked

Viewed 1,465 times

2

If I create a button...

<button id="btn" value="fui eu">Clique Aqui</button>

the event...

document.getElementById("btn").onclick = function(e){ console.log("Quem clicou "+e.target.value) };

Works legal!

But if I insert an image...

<button id="btn" value="fui eu"><img src="iconelegal.jpeg" /></button>

...then it doesn’t work because the target is the bitmap and not the button, since it is in front and is where you actually click. It makes sense, but it does not solve the problem! I think I once solved it with a gambiarra looking for the right relative, but now I’d like to know the right way to do it. Does anyone know?

EDIT: corrected the automatic correction... In that particular case, e.target.parentNode will find the button, there would be a more generic form?

  • judging that you at the time of writing the topic accidentally missed the parameter id of btn for bin, and that your code is all right, but that the error persists, see this same code in fsfiddle working (with img inside the button)

  • I fixed the corrector that changes btn to bin. The example returns Undefined. As I wrote above now, in this case it is solved with e.target.parentNode, but if I insert a more complex object it will no longer work again. There is no way to know the origin of the event?

2 answers

4


When you add an event headphone to an element the function that will be called runs with that element as context. This means that the this inside that function is the element to which you added the event headphone.

This function automatically receives an argument, the event that occurred and caused the function to be invoked. This event is an object with several properties, one of which the .target which is the element where the event began.

Let’s look at this example of HTML:

section
    div
       span 

where span is inside div which for its sake is inside Section.

When you do:

section.addEventListener('click', function(e){

this function will be run whenever there is a click on Section but also on one of its descendants. In fact all parent elements whose offspring have a trigger event see their addEventListeners to be called as well. You can avoid this by invoking e.preventPropagation(); inside the function. Outside the one apart, and returning to the example above this function will have as thisat all times the Section and how e.target always the element that receives the click.

Take a look at this example (link), where I create a way to verify that:

var section = document.querySelector('section');
section.addEventListener('click', handler(section));

function handler(elComAuscultador) {
    return function(e) {
        var target = e.target.tagName.toLowerCase();
        var self = this.tagName.toLowerCase();
        var log = [
            'Clicaste no elemento ' + target,
            'O this é o elemento ' + self,
            'this == elComAuscultador é verdadeiro? ' + (this == elComAuscultador ? 'sim' : 'não')
        ];
        alert(log.join('\n'));
    }
}
body > * {
    padding: 50px;
}

section {
    background-color: blue;
}

div {
    background-color: yellow;
}

p {
    background-color: red;
    width: 100px;
    height: 100px;
}
<section>section
    <div>div<p>span</p></div>
</section>

The same logic applies using section.onclick = function(e){ (example) but with a fatal difference, is that this method elemento.onclick = function(){ only allows one per widget and overwrites all others (example), while the elemento.addEventListener allows as many headphones as you want, and calls everyone when the event happens.

  • 1

    if he decides to implement the interface Eventlistener, the this will no longer be the DOM object to be the object implementing the interface, but in this case, the event.currentTarget continues to point to the DOM to which the event was tied, while the event.target will point to the DOM that activated the event.

  • Surely he (I) will want to implement via Eventlistener, thank you for supplementing the reply, I hope Sergio adds in his to make it even more complete.

2

Responding in an objective way,

In that code:

document.getElementById("btn").onclick = function(e){ console.log("Quem clicou "+e.target.value) };

Exchange for:

document.getElementById("btn").onclick = function(e){ console.log("Quem clicou "+this.value) };

Abstract: Just modify it e.target.value for this.value

  • Thanks Daniel, I just didn’t mark your answer as correct because I had to choose one, and the other was more complete.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.