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:
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.