简体   繁体   中英

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);
    }
}

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);
}

An iframe is a convenient way to do this. Here are the high level steps:

  1. Create a hidden iframe
  2. Load the remote url
  3. onload access the iframe content
  4. get your specific element

An iframe will be especially useful if your remote page includes JavaScript that modifies the page content (a simple ajax request wouldn't run the scripts).

This is definitely a situation where a library like jQuery really helps, as it'll make everything transparent for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM