Home > database >  Always getting the same span element as event
Always getting the same span element as event

Time:12-22

<span class=`close-button ind${i}` onclick="toggleModal1(this)">×</span>

The "i" value ranges from 0 to 27 and my toggleModal1 function goes like this:

function toggleModal1(event) {
    console.log(event);
}

whenever I click the "x" with some class, ind{x}, I'm always getting the span with class ind0. Why ?

I tried adding eventlisteners to them individually but still I'm getting the same span element.

my code: https://jsfiddle.net/pk4gt1ea/

CodePudding user response:

You could pass the i as argument to toggleModal1, like so:

<span class=`close-button ind${i}` onclick=`toggleModal1(${i})`>×</span>

and lookup the element using

document.querySelector(`.close-button.ind${arg}`)

if you need to.

CodePudding user response:

It's because of the way you're calling your modals.

For example, you have these two functions:

function toggleModal(ind) {   // I'll call this one 'openModal'
    modal.classList.toggle("show-modal");
}

function toggleModal1(event) { // I'll call this one 'closeModal'
    modal.classList.toggle("show-modal");
}

Your first function, openModal, receives a proper argument - if we were to log it to the console, we'll see that ind is the same as the number we clicked on, and before the modal opens.

The problem is that the modal which opens is actually not the one you want - you have 28 of them, and by using

modal.classList.toggle("show-modal");

you're actually opening the first one you run into. That's why you're always getting the same span event.

If you want to get the one you clicked on, you could do something like this (not the best solution for a variety of reasons):

function toggleModal(ind) {
    let elem = document.querySelectorAll(".ind" ind);

    // I'm assuming there's only one instance of .ind${ind}
    if(elem && elem[0]) {
        let modToShow = elem[0].parentNode.parentNode;
        //                     ^____ this takes us to the <div > parent
        //                                ^ ___ this takes us to the <div > grandparent of your .ind${ind}

        modToShow.classList.toggle("show-modal");
    }
}

Apart from this, you would have to change your toggleModal1(), as well - you could pass an argument, and handle it in the same manner:

function toggleModal1(event) {
    let elem = document.querySelectorAll(event);

    // I'm assuming there's only one instance of .ind${ind}
    if(elem && elem[0]) {
        let modToShow = elem[0].parentNode.parentNode;
        //                     ^____ this takes us to the <div > parent
        //                                ^ ___ this takes us to the <div > grandparent of your .ind${ind}

        modToShow.classList.toggle("show-modal");
    }
}

Or you can do it like this:

function toggleModal1() {
    let elem = document.querySelectorAll(".show-modal");

    if(elem) {
        let len = elem.length;
        for(let i = len-1; i >= 0; i--) {
            elem[i].classList.toggle("show-modal");
        }
    }
}

Or, if you assume that there can only be one occurrence of .show-modal (at the most) in your DOM:

function toggleModal1() {
    let elem = document.querySelectorAll(".show-modal");

    if(elem) {
        elem[0].classList.toggle("show-modal");
    }
}

However, as I said, this isn't the best way to go about it, and I'd suggest to go with what @Igor K suggested.

Also, you shouldn't need 28 modals. One would do the trick - you would just keep passing the ind value as you're doing now.

  • Related