javascript 动态创建标记的几种方法

javascript 动态创建标记的几种方法

学习JavaScript DOM编程艺术一书所做的一些笔记。

1、 传统技术document.write和innerHTML实现动态创建标记
document.write 可以方便地把字符串插入到文档里,样例如下。
test.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Test</title>
</head>
<body>
    <script>
        document.write("<p>This is inserted.</p>");
    </script>
    
    <div id="testdiv">
        <p>This is <em>my</em> content.</p>
    </div>
    
    <script type="text/javascript" src="scripts/example.js"></script>
</body>
</html>

example.js:

window.onload = function() {
	var testdiv = document.getElementById("testdiv");
	alert(testdiv.innerHTML);
}

特点:
  • js和html代码混杂在一起,是一种很不好的做法。
  • innerHTML属性在处理数据时很粗放,毫无细节可言。
  • 以上二者相比较,后者至少可以实现js分离。

2、 DOM方法createElement、createTextNode、appendChild和insertBefore动态创建标记
通过以下图片库的实现,理解这几个DOM方法是怎么使用的。

gallery.html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<title>Image Gallery</title>
	<link rel="stylesheet" href="styles/layout.css" media="screen" />	
	<script type="text/javascript" src="scripts/showPic.js"></script>
</head>
<body>
	<h1>Snapshots</h1>
	<!--
	<ul>	
		<li><a href="images/fireworks.jpg" οnclick="showPic(this); return false;" title="A fireworks display">Fireworks</a></li>
		<li><a href="images/coffee.jpg" οnclick="showPic(this); return false;" title="A cup of back coffee">Coffee</a></li>
		<li><a href="images/rose.jpg" οnclick="showPic(this); return false;" title="A red,red rose">Rose</a></li>
		<li><a href="images/bigben.jpg" οnclick="showPic(this); return false;" title="A famous clock">Big Ben</a></li>		
	</ul>
	-->	
	<ul id="imagegallery">	
		<li><a href="images/fireworks.jpg" title="A fireworks display">Fireworks</a></li>
		<li><a href="images/coffee.jpg" title="A cup of back coffee">Coffee</a></li>
		<li><a href="images/rose.jpg" title="A red,red rose">Rose</a></li>
		<li><a href="images/bigben.jpg" title="A famous clock">Big Ben</a></li>		
	</ul>
	<!--
	<img id="placeholder" src="images/placeholder.gif" alt="my image gallery" />
	<p id="description">Choose an image.</p>
	-->	
</body>
</html>
showPic.js:
function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {  
		window.onload = function() {
			oldonload();
			func();
		}
	}
}

// 自定义实现的insertAfter函数,因为js中只提供了insertBefore函数
function insertAfter(newElement,targetElement) {
	var parent = targetElement.parentNode;
	if (parent.lastChild == targetElement) {
		parent.appendChild(newElement);
	} else {
		parent.insertBefore(newElement,targetElement.nextSibling);
	}
}

// 通过该函数实现将原在html代码中展示图片和图片描述所使用的锚点,改为在js中动态去生成
// 实现了js和html代码的完全分离
function preparePlaceholder() {
	// 首先是标签可用性检查
	if (!document.createElement) return false;
	if (!document.createTextNode) return false;
	if (!document.getElementById) return false;
	if (!document.getElementById("imagegallery")) return false;
	// 创建一个元素节点img,并设置好它的各种属性
	var placeholder = document.createElement("img");
	placeholder.setAttribute("id","placeholder");
	placeholder.setAttribute("src","images/placeholder.gif");
	placeholder.setAttribute("alt","my image gallery");
	// 创建一个元素节点p
	var description = document.createElement("p");
	description.setAttribute("id","description");
	// 创建了一个文本节点desctext,并在下一步中将其添加为description的子节点
	var desctext = document.createTextNode("Choose an image");
	description.appendChild(desctext);
	// 找到图片库的元素id,然后把展示图片和说明文字使用的两个锚点放在其后
	var gallery = document.getElementById("imagegallery");
	insertAfter(placeholder,gallery);
	insertAfter(description,placeholder);
}

// 通过该函数将js与html分离,且在该函数中做出了多处优化设计
function prepareGallery() {
	// 检查当前浏览器是否理解getElementsByTagName
	if (!document.getElementsByTagName) return false;
	// 检查当前浏览器是否理解getElementsById
	if (!document.getElementById) return false;
	// 检查当前网页是否存在一个id为imagegallery的元素
	if (!document.getElementById("imagegallery")) return false;
	var gallery = document.getElementById("imagegallery");
	var links = gallery.getElementsByTagName("a");
	// 遍历imagegallery元素中的所有链接
	for ( var i=0; i<links.length; i++) {
		// 设置onclick事件,让它在有关链接被点击时完成以下操作:
			// 把这个链接作为参数传递给showPic函数
			// 取消链接被点击时的默认行为,不让浏览器打开这个链接。而同时在showPic函数调用失败时,又允许链接点击行为的平稳退化。
		links[i].onclick = function() {
			return showPic(this) ? false : true;
		}
		// 将键盘操作都视同为点击操作
		links[i].onkeypress = links[i].onclick;
	}
}

function showPic(whichpic) {
	// 检查当前网页是否存在一个id为placeholder的元素
	if (!document.getElementById("placeholder")) return false;
	var source = whichpic.getAttribute("href");
	var placeholder = document.getElementById("placeholder");
	// 检查placeholder元素的nodeName是否为IMG
	if (placeholder.nodeName != "IMG") return false;
	placeholder.setAttribute("src",source);
	// 检查description元素是否存在
	if (document.getElementById("description")) {
		// 检查title属性是否存在,利用三元操作符为找不到title属性时text变量的值为空字符串
		var text = whichpic.getAttribute("title") ? whichpic.getAttribute("title") : "";
		var description = document.getElementById("description");
		// 检查description元素的第一个子元素节点nodeType是否是文本节点
		if (description.firstChild.nodeType == 3) {
			description.firstChild.nodeValue = text;
		}	
	}
	return true;
}

// 触发浏览器加载页面后需要执行的js函数
addLoadEvent(preparePlaceholder);
addLoadEvent(prepareGallery);

3、Ajax方法实现动态创建标记
Ajax是一种异步加载页面的技术,其核心就是XMLHttpRequest对象,这个对象充当着浏览器和服务器之间的中间人的角色。以往的请求都是由浏览器发出,而js可以通过这个对象自己发送请求,同时也自己处理响应。

目前不同浏览器实现XMLHttpRequest对象的方式不太一样,为了保证跨浏览器,需要做一些兼容性设计。
从以下例子中,理解怎么使用该方法。在本样例中,先创建了一个XMLHttpRequest对象,然后从一个文本文件中获取了一段内容,在浏览器页面中进行展示。

ajax.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
    <title>Ajax</title>
</head>
<body>
    <div id="new"></div>
    <script src="scripts/getHTTPObject.js"></script>
    <script src="scripts/getNewContent.js"></script>
</body>
</html>
example.txt
This was loaded asynchronously!
getHTTPObject.js
function getHTTPObject() {
	if (typeof XMLHttpRequest == "undefined")
		XMLHttpRequest = function () {
			try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
				catch (e) {}
			try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
				catch (e) {}
			try { return new ActiveXObject("Msxml2.XMLHTTP"); }
				catch (e) {}
			return false;
		}
	return new XMLHttpRequest();
}
getNewContent.js
function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {  
		window.onload = function() {
			oldonload();
			func();
		}
	}
}

function getNewContent() {
	var request = getHTTPObject();
	if (request) {
		request.open( "GET", "example.txt", true);
		// onreadystatechange会在服务器给XMLRequest对象送回响应的时候被触发执行
		// 注意如果不是定义一个匿名处理函数,而是引用一个已定义的函数,则不要在函数名后加括号。
		// 因为加括号表示立即调用函数,而在此只想把函数自身的引用赋值给 onreadystatechange事件。
		request.onreadystatechange = function() {	
			// readyState有5个可能的值,分别是0表示未初始化,1表示正在加载,2表示加载完毕,3表示正在交互,4表示完成
			if (request.readyState == 4) {				
				var para = document.createElement("p");
				// 服务器返回的数据可以通过两个属性进行访问,一个是 responseText,另一个是 responseXML
				// responseXML保存的是Content-Type头部中指定为"text/xml"的数据,其实是一个 DocumentFragment对象,可以使用DOM方法处理。
				var txt = document.createTextNode(request.responseText);
				alert(request.responseXML);
				para.appendChild(txt);
				document.getElementById('new').appendChild(para);
			}
		};
		request.send(null);
	} else {
		alert('Sorry, your browser doesn\'t support XMLHttpRequest');
	}
}
addLoadEvent(getNewContent);
注:在使用Ajax时千万要注意同源策略。使用XMLHttpRequest对象发送的请求只能访问与其所在的HTML处于同一个域中的数据,不能向其他域发送请求。此外chome浏览器限制了Ajax使用file协议从自己的硬盘里加载文件,所以上面的代码在chome中会报错如下:
getNewContent.js:32 Failed to load file:///D:/work/gallery/example.txt: Cross origin requests are only supported for protocol schemes: http
注:因为原书出版时间较早,使用的例子已经不满足新版本浏览器的安全要求,以上样例中的使用方法在ie11中同样被禁用。了解即可,也可以手动打开下浏览器对js脚本的相关限制以便于观察效果。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值