Question

As my title suggests I want to restart jquery's setInterval without re-initializing it.

My scenario is that consider a page that is completely loaded. On this page a div gets added dynamically and randomly anytime after the page is completely loaded. I am not adding this div from my code behind so I do not have any control over this. This div has a class namely lpInviteChatHrefClose. This is fixed i.e. the div will always have this class. When the user clicks on this div, some javascript function executes and this div gets hidden. Also multiple div tags might get added (with the same class name) but if an existing, visible div tag is not clicked then a new div is not added.

Now, what I want to achieve is that I want to call a javascript function on click of this div. Now, since this div is dynamically added, I cannot write the following as jquery will not be able to find the div on document.ready

$('.lpInviteChatHrefClose').click(function(){...});

So what I did is I created a setInterval which checks if such div exists, if yes then bind the click event. I was able make this work when the first time the dynamic div gets added.

My problem arises when the second time this dynamic div gets added to the html. Here again i need to handle the click event of the new dynamically added div.

What I have done so far is as follows

outside document.ready (global)

 var interval;

 var onInterval;

inside document.ready

onInterval = function () {
    //check if an element with this class exists
    if ($('.lpInviteChatHrefClose').length) {
        $(".lpInviteChatHrefClose").click(function () {
            outbound_reject_omniture_setting(this);
            //This should restart the interval but it doesnt
            interval = setInterval(onInterval, 1000);
        });
        clearInterval(interval);
    }
};

interval = setInterval(onInterval, 1000);

I would have done away with this check if ($('.lpInviteChatHrefClose').length) but then the setInterval will attach a function after every 1 second as soon as the dynamic div appears. I do not want this. I want that my javascript function should get called only once.

The clearInterval(interval); will stop/pause the interval. But I have no idea how to restart it.

Please help!

Sorry for the long description. Thanks in advance!

Was it helpful?

Solution 3

I was able to achieve this.

The problem was that the setInterval was getting restarted (an observation mistake you can say) but it was getting bound immediately to an earlier element which was created dynamically hence new element which was getting added after certain period of time was not getting bound.

Also as I mentioned that the method which was getting called i.e. outbound_reject_omniture_setting was doing some work and then the element was getting hidden, so I was not able to check if the click is getting bound to the same element.

The solution was to loop through all the elements that are added till now dynamically and check if any 1 of them is visible. If yes then bound the click event to the element and clear the interval. Within the click function, restart the interval.

onInterval = function () {
    $('.lpInviteChatHrefClose').each(function (index) {
        if ($(this).css('visibility') == 'visible') {
            $(this).click(function () {
                outbound_reject_omniture_setting(this);
                interval = setInterval(onInterval, 1000);
            });
            clearInterval(interval);
        }

    })
};

interval = setInterval(onInterval, 1000);

Thank you everyone for your help.

OTHER TIPS

You need to use a delegated event handler to attach events to elements which are created after DOMready has fired. Forget anything to do with setTimeout or setInterval.

$(document).on('click', '.lpInviteChatHrefClose', function(){
    // your code here...
});

you dont have to use setInterval for dynamic elements. Use event delegation for that

$(document).on('click','.lpInviteChatHrefClose',function(){...});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top