Dariush
Dariush

Reputation: 483

visibilitychange doesn't behave as intended

The MDN page for visibilitychange states that "it is fired when the content of a tab has become visible or has been hidden". However, when I run the following snippet, I immediatly get an infinite chain of alerts, so it is apparently being fired constantly. Why is this happening?

function doEverything() {
    if(document.visibilityState == 'visible') {
        alert(document.visibilityState);
        document.removeEventListener("visibilitychange", doEverything());
    }
}

document.addEventListener("visibilitychange", doEverything());

Upvotes: 1

Views: 1690

Answers (2)

boombox
boombox

Reputation: 2456

Why is this happening?

The reason is because you are constantly executing the doEverything function in a never-ending loop.

1) doEverything() is first executed here:

document.addEventListener("visibilitychange", doEverything());

2) doEverything() goes into a loop here, constantly displaying the alert:

function doEverything() {
    if(document.visibilityState == 'visible') {
        alert(document.visibilityState);
        document.removeEventListener("visibilitychange", doEverything());
    }
}

The above can be seen as the equivalent of:

function doEverything() {
    if (true) {
        doEverything(); // loop
    }
}

To fix this, you don't want to execute the function but rather provide the reference of the function. It's a simple change from doEverything() to doEverything in your addEventListener() and removeEventListener():

function doEverything() {
    if(document.visibilityState == 'visible') {
        console.log('hi');
        document.removeEventListener("visibilitychange", doEverything);
    }
}

document.addEventListener("visibilitychange", doEverything);

This will run the alert only once when the tab is switched.

Upvotes: 1

Omar Elawady
Omar Elawady

Reputation: 3350

you are calling the function instead of passing it as argument.

document.addEventListener("visibilitychange", doEverything);

and

document.removeEventListener("visibilitychange", doEverything);

Upvotes: 1

Related Questions