Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using AJAX to get a specific DOM Element (using Javascript, not jQuery)

How do you use AJAX (in plain JavaScript, NOT jQuery) to get a page (same domain) and display just a specific DOM Element? (Such as the DOM element marked with the id of "bodyContent").

I'm working with MediaWiki 1.18, so my methods have to be a little less conventional (I know that a version of jQuery can be enabled for MediaWiki, but I don't have access to do that so I need to look at other options). I apologize if the code is messy, but there's a reason I need to build it this way. I'm mostly interested in seeing what can be done with the Javascript.

Here's the HTML code:

<div class="mediaWiki-AJAX"><a href="http://www.domain.com/whatever"></a></div>

Here's the Javascript I have so far:

var AJAXs = document.getElementsByClassName('mediaWiki-AJAX');
if (AJAXs.length > 0) {
    for (var i = AJAXs.length - 1; i >= 0; i--) {
        var URL = AJAXs[i].getElementsByTagName('a')[0].href;
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                AJAXs[i].innerHTML = xmlhttp.responseText;
            }
        }
        xmlhttp.open('GET',URL,true);
        xmlhttp.send();
    }
}


EDIT:

Thanks to the answer lbstr gave, I was able to come up with the following, which works! You'll note that I added in extra steps to remove any elements that I didn't want. For whatever reason, getElementById() didn't work on the responseText, but getElementsByClassName() did. I imagine it's because the ID of "bodyContent" already exists on the wiki page prior to the AJAX call being run.

//This function is necessary to read the response text correctly.
function outerHTML(node){
    // if IE, Chrome take the internal method otherwise build one
    return node.outerHTML || (
    function(n){
        var div = document.createElement('div'), h;
        div.appendChild( n.cloneNode(true) );
        h = div.innerHTML;
        div = null;
        return h;
    })(node);
}

// This code deals with populating the AJAX divs within a wiki page.
var AJAXs = document.getElementsByClassName('mediaWiki-AJAX');
if (AJAXs.length > 0) {
    for (var i = AJAXs.length - 1; i >= 0; i--) {
        (function(index){
            var URL = AJAXs[index].getElementsByTagName('a')[0].href;
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function() {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    var tempDiv = document.createElement('div');
                    tempDiv.innerHTML = xmlhttp.responseText;
                    var AJAXContent = tempDiv.getElementsByClassName('mw-content-ltr')[0];

                    //Remove unnecessary "fixed" items to avoid clutter.
                    var hiddenItems = AJAXContent.getElementsByClassName('hidden-item');
                    if (hiddenItems.length > 0) {
                        for (var j = hiddenItems.length - 1; j >= 0; j--) {
                            AJAXContent.removeChild(hiddenItems[j]);
                        }
                    }
                    var protectedItems = AJAXContent.getElementsByClassName('protected-item');
                    if (protectedItems.length > 0) {
                        for (var j = protectedItems.length - 1; j >= 0; j--) {
                            AJAXContent.removeChild(protectedItems[j]);
                        }
                    }

                    //Insert the AJAX content and rerun Javascript on it.
                    if (AJAXContent !== null && AJAXContent !== undefined) {
                        AJAXs[index].innerHTML = outerHTML(AJAXContent);
                        assign_Popup_Functions(AJAXs[index]);
                        fix_External_Links(AJAXs[index]);
                        assign_iFrame_Functions(AJAXs[index]);
                    }
                }
            }
            xmlhttp.open('GET',URL,true);
            xmlhttp.send();
        })(i);
    }
}
like image 704
Matt Frost Avatar asked Aug 15 '26 19:08

Matt Frost


1 Answers

it seems like in your callback you could just do this:

var temp = document.createElement("div");
temp.innerHTML = xmlhttp.responseText;
var bodyContent = temp.getElementById("bodyContent");
if (bodyContent !== null && bodyContent !== undefined) {
    AJAXs[i].innerHTML = outerHTML(bodyContent);
}

Given this outerHTML function from this SO post:

function outerHTML(node){
    // if IE, Chrome take the internal method otherwise build one
    return node.outerHTML || (
    function(n){
        var div = document.createElement('div'), h;
        div.appendChild( n.cloneNode(true) );
        h = div.innerHTML;
        div = null;
        return h;
    })(node);
}

Keep in mind that if you are doing this to multiple AJAXs containers, you could end up with multiple items wiht the same ID (bodyContent). Make sure you come up with some way to avoid that. Maybe you want innerHTML instead?

EDIT:

I also forgot to point out a bug that will arise with your setup. Since your callback will be reached after the loop is done, the value of i will always be 0, so you won't update the correct container. You'll need to do something like this:

for (var i = AJAXs.length - 1; i >= 0; i--) {
    (function(index){
        var URL = AJAXs[index].getElementsByTagName('a')[0].href;
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                AJAXs[index].innerHTML = xmlhttp.responseText;
            }
        }
        xmlhttp.open('GET',URL,true);
        xmlhttp.send();
    })(i);
}
like image 126
lbstr Avatar answered Aug 17 '26 09:08

lbstr