Francesca
Francesca

Reputation: 28148

Running jQuery scripts on DOM elements loaded with AJAX

I understand that jQuery will not run when the DOM content is being loaded via AJAX. But I'm confused as to the reason why. My understanding was that the DOM elements didn't exist at the time the jQuery was initiated therefore it won't find the correct IDs or classes.

But I have a situation where the jQuery is only called AFTER all the content has been loaded via AJAX. yet it still does not work.

Here is my code. I am trying to get the function decorateGains() to run after AJAX completes.

loadData('7-days'); // Runs the default AJAX for 7 days
function loadData(type){
    var xmlhttp;
    if (window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}
    else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
    xmlhttp.onreadystatechange=function()
      {
        if (xmlhttp.readyState==4 && xmlhttp.status==200){document.getElementById("home-table").innerHTML=xmlhttp.responseText;}
      }
    xmlhttp.open("GET","actions/get-data-"+type+".php",true);
    xmlhttp.send();
    decorateGains();
}

You can see that I am including a call to the function decorateGains() right at the end of the loadData() function.

The decorateGains() function does run, as I can see my console message. However it does not do the task that it should.

function decorateGains() {
    console.log('here');
    $(".gains").each(function() { 
        var num = +($(this).text());
        if (num > 0) {
            console.log('here');
            $(this).addClass("positive");
        }
        if (num < 0) {
            console.log('here');
            $(this).addClass("negative");
        }
    });
}

(The script searches for all elements with a class of .gains and adds a new class of positive or negative depending on the content of the element. Essentially it decorates the .gains element to be red or green depending on whether the number is negative or positive).

Upvotes: 1

Views: 86

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337560

This is because the AJAX call is asynchronous. The request has not been completed (and therefore the new content has not been appended to the DOM) when you call your decorateGains() function. You need to place the call to the function inside the onreadystatechange handler, after setting the innerHTML:

loadData('7-days'); // Runs the default AJAX for 7 days
function loadData(type) {
    var xmlhttp;
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
    } else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            document.getElementById("home-table").innerHTML = xmlhttp.responseText;

            decorateGains(); // <-- move this in here
        }
    }
    xmlhttp.open("GET", "actions/get-data-" + type + ".php", true);
    xmlhttp.send();
}

Upvotes: 2

Related Questions