Search code examples
javascriptmessage

window message Event firing more than one time sometime


I have an IFrame in my page. I'm using postmessage to establish a communication between the script of parent page and child page. I also have a polar to reflect the Iframe minimize and maximize state in all tab using cookie.

But the problem is that I've a counter which will actually increase when my child page send a message with special object. But the message event fires in the parent page more than one times. If it fires more than one time the counter will be wrong. This is not happening consistently. Sometimes it working perfectly and sometime not. Does it have any relation with the polar? Because when I comment this everything working fine.

Here this the listener

function listenIframe() {
    var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
    var eventer = window[eventMethod];       

    var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

    // Listen to message from child IFrame window
    eventer(messageEvent, function (e) {
        if (e.data == xyz) {
            close();
        } else if (e.data == abcd) {
           //increase Count;
        }
    }, false);
}

Here is the poller

function fn(start) {
    var x, y, z;

    if (start) {
        j.k= setTimeout(function stateChangePollar() {
            // show or hide logic here

            setTimeout(stateChangePollar, 1000);
        }, 1000);
    }
    else {
        clearTimeout(j.k);
    }
}

Solution

  • When is your listenIframe called? Can it be that it's called multiple times? The best way would be to ensure that it only gets called once, otherwise one solution would be to store something in an outside variable to check it, like this:

    let isListenerAttached = false;
    
    function listenIframe() {
        if (isListenerAttached) return;
        isListenerAttached = true;
    
        var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
        var eventer = window[eventMethod];       
    
        var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
    
        // Listen to message from child IFrame window
        eventer(messageEvent, function (e) {
            if (e.data == xyz) {
                close();
            } else if (e.data == abcd) {
               //increase Count;
            }
        }, false);
    }
    

    This is not an optimal solution though, it can easily get messy by handling this with outside variables. Especially if it'll be a global variable. The best solution would be to ensure that listenIframe is only called once.