PowerUser
PowerUser

Reputation: 812

Change page content with AJAX, then execute JS

Hello so I have the following code:

function loadXMLDoc()
{
    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("text").innerHTML=xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET","data.html",true);
    xmlhttp.send();
}

And my button:

<a href="#" id="change-btn" onclick="loadXMLDoc(); return true;">Change page</a>

And my other script:

$(document).ready(function(){
    $("#change-btn").click(function(event) {
        event.preventDefault();
        $('html, body').animate({
            scrollTop: $("#page-changed").offset().top
        }, 2000, "swing", function(){
            $("#page-changed").effect('shake', {times: 1, direction: 'left', distance: 5}, 300);
        });
});

This works well if #page-changed is on top of the data.html file. But if it's at the bottom jQuery returns error that offset.top is undefined I understand that the problem is that jQuery can't find the #page-changed element in time and returns undefined. How to fix this?

Upvotes: 0

Views: 112

Answers (1)

Terry
Terry

Reputation: 66228

AJAX is performed asynchronously (as its name suggests), so you should wait for the AJAX call to be completed before changing the scroll position of the page. Also, since you are already using jQuery, then you can reduce your code for the AJAX call to using $.ajax() (or $.get(), which is a shorthand for GET requests), which is a lot simpler, and natively returned promises (which we listen on to check if AJAX call is complete).

Given your HTML, we remove the inline JS:

<a href="#" id="change-btn">Change page</a>

For your JS, that is quite simple—although you will need to fill in the details for the AJAX call yourself:

$('#change-btn').click(function(e) {

    // Prevent default
    e.preventDefault();

    // Make a GET request for data.html
    var loadXMLDoc = $.get({
        'url': 'data.html'
    });

    // Perform things when AJAX call is successful
    loadXMLDoc.done(function(data) {
        // Set innerHTML of #text element
        $('#text').html(data);

        // Then set scroll position
        $('html, body').animate({
            scrollTop: $("#page-changed").offset().top
        }, 2000, "swing", function(){
            $("#page-changed").effect('shake', {
                times: 1,
                direction: 'left',
                distance: 5
            }, 300);
        });
    })

});

Upvotes: 1

Related Questions