Problem of children in javascript

Asked

Viewed 48 times

0

Good afternoon, I have a project this way:

<div data-id="codexample" class="abc">
   <div class="container">
      <div class="btn">
         <p>Teste</p>
      </div>
   </div>
</div>

I wanted the div container to be clickable and your children to be clickable, but I also wanted regardless of where it was clicked to be able to return the div’s data-id. abc But using chieldNode as the click reference changes, I can’t always return the data-id. How do I solve this problem?

Example of the code that is actually in the project:

const adis = document.getElementsByClassName("adi");

for (var i = 0; i < adis.length; i++) {
    adis[i].addEventListener("click", function(target){
        var idProduct;
        idProduct = target.target.parentNode.getAttribute("data-prodId");
        const questdel = confirm('Pretende realmente remover o produto ' + prodName + ' do carrinho?');
        if(questdel){
            delete cart[idProduct]; 
            localStorage.setItem("cart", JSON.stringify(cart));
        }
    });
};

Inside the . Adi I have other sub-components, but the . Adi is the main clickable top, and the others inherit this property normally, but returns the . bad id, depending on the click place.

At the request of the comments here is the html code (with JS variables):

<div class="cartBox">
    <table id="cartTable">
        <tr>
            <td><p>Imagem</p></td>
            <td><p>Produto</p></td>
            <td><p>Quantidade</p></td>
            <td><p>Sub-Preço</p></td>
            <td><p>Ação</p></td>
        </tr>
        <tr data-prodId="' + key + '">
            <td><img src="' + data['imagePath'] + '" title="' + data['nome'] + '"></td>
            <td><p class="nameProd">' + data['nome'] + '</p></td>
            <td><input type="number" min="1" max="15" class="nqtd qtdpc" placeholder="QTD" value="' + cart[key].inCart + '" required autocomplete="off" required autocapitalize="off" /></td>
            <td><p>' + subtotal + '€</p></td>
            <td><div class="actionDelete adi"><p><i class="fas fa-trash"></i></p></div></td>
        </tr>
        <tr>
            <td class="totalText" colspan="4"><p>Total:</p></td>
            <td><p class="totalPc"></p></td>
        </tr>
    </table>
</div>
  • Make the HTML structure more complete, where the elements are .adi and .prod-id?

  • I’ve already added HTML

  • 1

    This answers your question? Return parent tag ID when clicking a button. There are other similar questions that may also help, search through the community for parentElement

  • The problem is that the click reference on this question does not change, in my changes.

  • 1

    It doesn’t make much difference, it takes the father, if it’s not what he wants, it takes his father, and so on, the logic is the same. Something like, while (!el.hasAttr("data-prodId")) el = el.parentElement;. This is just a demo code, it won’t work

  • https://i.ibb.co/yWNfLHS/image.png here is the problem, (ignore the errors in red), but according to the click zone once it returns to tbody again it returns to tr, and I wanted it to return if always to tr for me to get the data-prodId

  • Thanks Costamilam, I’ll try to adapt this.

  • So your real code is very dirferente that posted, nor has a tbody in the HTML you posted, and click on tbody will not fire the event at a child element. Be careful with this when asking questions, the example should minimum, but also complete, beyond verifiable. Also do not snippet if your code is only demostrative and not an executable. Understand better: https://pt.meta.stackoverflow.com/q/8388/

  • Thanks, that while tip, it worked. My code do not have tbody, it is that on the console appeared, n know pq. Okay, in such cases I will no longer put snippets.

Show 5 more comments

1 answer

1


Hello, all right?

This problem occurs because you are using the target property of the event object. This property refers to the element that originated the event, so not always what you want. Below the quote from the MDN documentation on the Event.target

A reference to the object that sent the event. It is different from Event.currentTarget when the event handler is called during the bubbling phase or event capture.

To work the way you want, you should use the property currentTarget, that will return the element responsible for the event (in your case, div . abc)

const adis = document.getElementsByClassName("adi");

for (var i = 0; i < adis.length; i++) {
    adis[i].addEventListener("click", function(target){
        var idProduct;
        idProduct = target.currentTarget.parentNode.getAttribute("data-prodId");
        const questdel = confirm('Pretende realmente remover o produto ' + prodName + ' do carrinho?');
        if(questdel){
            delete cart[idProduct]; 
            localStorage.setItem("cart", JSON.stringify(cart));
        }
    });
};

Another more elegant solution would be to use the this, which in this case also refers to the element that you defined the event

const adis = document.getElementsByClassName("adi");

for (var i = 0; i < adis.length; i++) {
    adis[i].addEventListener("click", function(){
        var idProduct;
        idProduct = this.parentNode.getAttribute("data-prodId");
        const questdel = confirm('Pretende realmente remover o produto ' + prodName + ' do carrinho?');
        if(questdel){
            delete cart[idProduct]; 
            localStorage.setItem("cart", JSON.stringify(cart));
        }
    });
};

Browser other questions tagged

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