Toggle the text of an element with each click

Asked

Viewed 63 times

2

I’m willing to keep changing what’s written in the DOM as a loop. But when he goes to the end of the teste1 and calls the teste, should not start the function again teste?

document.addEventListener("click", principal)

function principal() {

    document.addEventListener("click", teste)

    function teste() {
        document.querySelector('div#mod').innerText = 'Claro'
        document.addEventListener("click", teste1)
    }

    function teste1() {
        document.querySelector('div#mod').innerText = 'Escuro'
        document.addEventListener("click", teste)
    }
}

2 answers

3

If you just want to keep changing the text every time a click occurs, you don’t need one loop, let alone register the same functions several times. Just register once, a single function that checks the current text and changes it to the other value:

document.addEventListener("click", function() {
    let elemento = document.querySelector('div#mod');
    if (elemento.innerText === 'Claro') {
        elemento.innerText = 'Escuro';
    } else {
        elemento.innerText = 'Claro';
    }
});
Clique para mudar o texto<br>
<div id="mod">
</div>

Note that so you don’t need to keep registering functions at all times. Simply register Listener once, the function takes care to check the current text and change it.


If you want to have several text options and switch between them, an alternative is to create an array with the possible texts and iterate through them:

var opcoes = ['Claro', 'Escuro', 'Branco', 'Cinza'];
var counter = 0;
document.addEventListener("click", function() {
    document.querySelector('div#mod').innerText = opcoes[counter];
    counter = (counter + 1) % opcoes.length;
});
Clique para mudar o texto<br>
<div id="mod">
</div>

The operator % (rest of the split) ensures that I return to the beginning of the array when the counter exceeds the size of the same.


Because your code didn’t work

The way you did, you were booking a Listener new with each click, because addEventListener has cumulative effect: every time you call her, you’re registering a new Listener, which will be executed along with others who were already registered. This causes the functions to be performed several times.

See the example below (it is basically your code with some modifications to understand better what is happening):

var i = 0;
document.addEventListener("click", principal);

function principal() {
    console.log(i++, 'principal');
    document.addEventListener("click", teste);

    function teste() {
        console.log(i++, 'Claro');
        document.addEventListener("click", teste1);
    }

    function teste1() {
        console.log(i++, 'Escuro');
        document.addEventListener("click", teste);
    }
}
Clique para disparar as chamadas das funções<br>
<div id="mod">
</div>

First we register the function principal in the click event.

And the first time you click, it performs the function principal, that does not call the other functions (she only registers the click event to call the function teste, but teste not yet called here) and prints "0 principal".

Then, when you click again, it performs the function principal (printing "1 principal" and records another click event to call teste - I mean, we now have 2 calls to teste registered). Then the function is executed teste (which was recorded when we first clicked), which prints "2 Claro" and records the click event to call teste1.

Next time you click, it runs principal, teste twice (as we record the respective event twice) and teste1 (printing "3 principal", "4 Claro", "5 Claro" and "6 Escuro"). Remembering that the call to principal records another event to call teste, and every call from teste records another event to call teste1.

And teste1, in turn, records another click event to call teste (that will register another event to call teste1 every time it is called and so on). After a few clicks, it will be impossible to control and understand what is happening.

So the best solution is to register the event only once.

2

It’s one thing to register an event headphone document.addEventListener; another thing is to activate it. To activate an event handset you need to click on the page (in this case the event click) or trigger a synthetic event.

To trigger a synthetic event you can do so:

var event = new Event('click');

// Listen for the event.
document.addEventListener('click', function(e) {
  console.log('Clique!!', e.isTrusted);
}, false);

// Dispatch the event.
document.dispatchEvent(event);
Clica aqui também...

Notice that the synthetic has the property isTrusted as false, but it works for a certain type of functionality.

Heed:

  • chaining mutually calling functions can generate an infinite loop and make the browser stop.
  • each time you run these functions you are adding new event headphones. All will be called when there is a clique on the page, which in turn will add even more headphones...

Browser other questions tagged

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