第一件事。尽量不要使用document.write
这种方法,因为当 DOM 准备好和仍在初始化时,这种方法的行为会反复无常。它被认为是一种不好的做法。
我还建议使用函数来分解代码的复杂性并使其更具可读性。
您应该知道 XHR 对象不是同步的。您需要等待通过readystatechange
事件检索 xml 数据。
最后,您不必在浏览器中构建 html 字符串。DOM API 允许您将锚点和图像标签创建为可以附加到 DOM 树的适当节点。
希望有帮助。
(function() {
//fetch the gallery photos
getXML('include/photoLibrary.xml', function(xml) {
var photos, pI, photo, anchor, image, anchors = [];
//pick four photos at random
photos = getRandom(makeArray(xml.getElementsByTagName('photo')), 4);
//build out each photo thumb
for(pI = 0; pI < photos.length; pI += 1) {
photo = photos[pI];
//create the anchor
anchor = document.createElement('a');
anchor.setAttribute('href', photo.getElementsByTagName('path')[0].childNodes[0].nodeValue);
anchor.setAttribute('class', 'lytebox');
anchor.setAttribute('data-lyte-options', 'group:vacation');
anchor.setAttribute('data-title', photo.getElementsByTagName('description')[0].childNodes[0].nodeValue);
//create the image
image = document.createElement('img');
image.setAttribute('src', photo.getElementsByTagName('thumb')[0].childNodes[0].nodeValue);
image.setAttribute('alt', photo.getElementsByTagName('title')[0].childNodes[0].nodeValue);
//insert the image into the anchor
anchor.appendChild(image);
//insert the anchor into the body (change this to place the anchors else were)
anchors.push(anchor);
}
//when the DOM is loaded insert each photo thumb
bind(window, 'load', function() {
var aI;
for(aI = 0; aI < anchors.length; aI += 1) {
//replace document.body with whatever container you wish to use
document.body.appendChild(anchors[aI]);
}
});
});
/**
* Fetches an xml document via HTTP method GET. Fires a callback when the xml data
* Arrives.
*/
function getXML(url, callback) {
var xhr;
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if(window.ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} else {
throw new Error('Browser does not support XML HTTP Requests.');
}
//attach the ready state hander and send the request
xhr.onreadystatechange = readyStateHandler;
xhr.open("GET","photos.xml",false);
xhr.send();
function readyStateHandler() {
//exit on all states except for 4 (complete)
if(xhr.readyState !== 4) { return; }
//fire the callback passing the response xml data
callback(xhr.responseXML);
}
}
/**
* Takes array likes (node lists and arguments objects) and converts them
* into proper arrays.
*/
function makeArray(arrayLike) {
return Array.prototype.slice.apply(arrayLike);
}
/**
* Extracts a given number of items from an array at random.
* Does not modify the orignal array.
*/
function getRandom(array, count) {
var index, randoms = [];
//clone the original array to prevent side effects
array = [].concat(array);
//pull random items until the count is satisfied
while(randoms.length < count) {
index = Math.round(Math.random() * (array.length - 1));
randoms.push(array.splice(index, 1)[0]);
}
return randoms;
}
function bind(element, eventName, callback) {
if(typeof element.addEventListener === 'function') {
return element.addEventListener(eventName, callback, false);
} else if(typeof element.attachEvent === 'function') {
return element.attachEvent('on' + eventName, callback);
}
}
})();
编辑:修复了三个错误。在插入节点之前需要加载 DOM。XML 节点没有 innerHTML 属性。Array.concat 不会将 DOM NodeList 对象视为数组。