动态创建标记+图片库最终版

HTML标记负责创建网页结构,而JavaScript则用来改变细节,同时JS也能通过动态创建新元素,修改旧元素来改变网页结构.
在这里插入图片描述

传统方法

在将文本节点插入到文档中时,在过去经常用到document.write和innerHTML两种方法:
(1)document.write方法

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>动态创建标记</title>
	<script src="动态创建标记.js"></script>
</head>
<body>
	<script type="text/javascript">
		document.write("<p>用document.write()方法插入文本</p>");
	</script>
</body>
</html>

结果:
用document.write()方法插入文本

document.write最大的缺点是它违背了 “ 行为应该与表现分离 ”的原则。即使把document.write语句挪到文档外,也需要用< scripte >标签来调用。

(1)document.innerHTML()方法

innerHTML会返回element的所有文本节点,也就是标签之间的所有文本支持读写,另外值得注意的是:一旦使用innerHTML属性插入,它就会将element的文本节点全部替换为要插入的内容.所以要结合DOM方法精细的处理标记.

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>动态创建标记</title>
	<script src="test.js"></script>
</head>
<body>
	<div id="test"></div>
</body>
</html>

window.onload=function()
{
	var test=document.getElementById("test");
	test.innerHTML="<p> 使用innerHTML插入文本节点</p>";//写入
	alert(test.innerHTML);//读取
}

在这里插入图片描述
在这里插入图片描述
innerHTML比document.write更有使用价值,但是和.write一样,只对HTML标记有效,对于其他的标记语言(XHTML)将不再收到支持.


DOM方法

DOM添加节点的步骤无外乎3步:创建节点,设置节点样式,添加至DOM树中,以下是步骤中用到的方法:
在这里插入图片描述

1. createTextNode, createelement, appendChild.方法:

创建一个元素节点,在元素节点内部用innerHTML插入文本,弹出test的文本:

window.onload=function()
{
	var test=document.getElementById("test");
	var para=document.createElement("p");//创建一个p类型的元素节点
	para.innerHTML="插入一个元素节点,内部插入文本";
	test.appendChild(para);
	alert(test.innerHTML);
}

结果如下:
在这里插入图片描述
在这里插入图片描述
创建一个元素节点,在元素节点内部用createTextNode插入文本节点,弹出test的文本:

window.onload=function()
{
	var test=document.getElementById("test");
	var para=document.createElement("p");//创建一个p类型的元素节点
	var txt=document.createTextNode("用createTextNode创建文本节点,并添加在para上");
	para.appendChild(txt);
	test.appendChild(para);
	alert(test.innerHTML);
}

可以看到使用innerHTML似乎更加简洁,但是别忘了,innerHTML只对HTML标记有用,而DOM方法对所有的标记有效,为了确保网页的稳定性,建议使用DOM标准的createTextNode:

练习:
要在body的div标签内插入如下所示的片段:

<body>
	<div id="test"></div>
</body>
</html>
<div>This is<img src=""><p>image</p></div>

片段的结构图如下
在这里插入图片描述
我们将按照如下步骤进行:
(1)创建div元素节点
(2)创建This is文本节点
(3)创建img元素节点,设置src属性
(4)创建p元素节点
(5)创建image文本节点
(6)将子节点插入到div节点
(7)按ID查找test节点,片段插入节点树

window.onload=function()
{
	var division=document.createElement("div");
	var txt1=document.createTextNode("This is");
	var image=document.createElement("img");
	image.href="picture.jpg";
	var para=document.createElement("p");
	var txt2=document.createTextNode("image");
	para.appendChild(txt2);
	division.appendChild(txt1);
	division.appendChild(image);
	division.appendChild(para);
	var div=document.getElementById("test");
	div.appendChild(division);
	alert(div.innerHTML);
}

在这里插入图片描述
appendChild是将元素添加在节点树的末尾,有优先次序的问题值得注意。想要插入在指定位置,我们还需要用到insertBefore和insertAfter方法

2. insertBefore和insertAfter方法

我们可以用insertBefore和insertAfter方法将节点插入到指定位置之前或者之后,这里我们重新回到图片库来解析这两个方法的使用。在此之前,我们发现,HTML标记里的最后一行:

<img id="placeholder" src="images/7.png" height="300" width="400" alt="my image gallery"/>
<p id="description">Choose a image</p>

提供挂钩仅仅是为了JavaScript的showPic函数服务的,如果我们让JavaScript动态的创建标记那再好不过,我们现在创建一个preparePlaceHolder函数来生成这两个节点

function preparePlaceHolder()
{
	var placeholder=document.createElement("img");
	placeholder.setAttribute("id","placeholder");
	placeholder.setAttribute("src","images/7.png");
	placeholder.setAttribute("alt","This is my photoGallery");
	placeholder.setAttribute("height","300");
	placeholder.setAttribute("width","400");
	var description=document.createElement("p");
	description.setAttribute("id","description");
	var txt=document.createTextNode("Choose an image");
	description.appendChild(txt);
	document.body.appendChild(placeholder);
	document.body.appendChild(description);
}

值得注意的是整函数的最后两行,我们直接用DOM提供的属性body来添加appendChild,将两个子元素节点添加在末尾。但是这只是一个巧合,body的末尾恰好就是这两个元素的位置。我们现在想使用 insertBefore和insertAfter方法来插入节点。

(1) parent.insertBefore(newElement,targetElement)

把一个新元素插入到一个旧元素的前面,他们互为兄弟节点,元素节点不允许插入在属性节点和文本节点之后:

var photoGallery=document.getElementById("photoGallery");
photoGallery.parentNode.insertBefore(placeholder,photoGallery);
photoGallery.parentNode.insertBefore(description,photoGallery);

这里使用了parentNode方法来获取目标节点的父元素,是一种通用的方法,把placeholder作为photoGallery的兄弟元素插入到photoGallery之前。description作为photoGallery的兄弟元素插入到photoGallery之前:
在这里插入图片描述

(2)insertAfter(newElement,targetElement)

效果似乎还不错,但是这不是我们想要实现的,我们想把placeholder和description插入到photoGallery之后,这个时候我们想设计一个函数insertAfter来在指定元素后面插入兄弟元素:

function insertAfter(newElement,targetElement)
{
	var parent=targetElement.parentNode;//获取目标的父节点
	if(parent.lastChild==targetElement)
	{
		parent.appendChild(newElement);
	}
	else
	{
		parent.insertBefore(newElement,targetElement.nextSibling);
	}
}

这里用到的几个新方法属性:
(1)获取子节点数组中的最后一个节点parent.lastChild
(2)获取元素节点的右兄弟节点nextSibling(使用前要判断是否有右兄弟节点)
这样一来我们就能使用insertAfter属性方法了:

	//photoGallery.parentNode.insertBefore(placeholder,photoGallery);
	//photoGallery.parentNode.insertBefore(description,photoGallery);
	insertAfter(placeholder,photoGallery);
	insertAfter(description,placeholder);

在这里插入图片描述
对于insertAfter方法,虽然不存在于DOM标准中,但是确实通用的,因为我们用DOM方法编写,具有普适意义,我们完全有必要掌握编写方法。

最后我们给preparePlaceHolder方法向后兼容,检验一些DOM方法功能是否可用:

function preparePlaceHolder()
{
	if(!document.createTextNode) return false;
	if(!document.createElement) return false;
	if(!document.getElementById) return false;
	if(!document.getElementById("photoGallery")) return false;
	var placeholder=document.createElement("img");
	placeholder.setAttribute("id","placeholder");
	placeholder.setAttribute("src","images/7.png");
	placeholder.setAttribute("alt","This is my photoGallery");
	placeholder.setAttribute("height","300");
	placeholder.setAttribute("width","400");
	var description=document.createElement("p");
	description.setAttribute("id","description");
	var txt=document.createTextNode("Choose an image");
	description.appendChild(txt);
	var photoGallery=document.getElementById("photoGallery");
	//photoGallery.parentNode.insertBefore(placeholder,photoGallery);
	//photoGallery.parentNode.insertBefore(description,photoGallery);
	insertAfter(placeholder,photoGallery);
	insertAfter(description,placeholder);
}

最后版本的图片库就设置完毕了,这个图片库虽说功能不算是齐全,但是对提高网页的可访问性和可用性,考虑了如下问题:平稳退化,向后兼容,分离JavaScript,同时也考虑一些优化,键盘访问属性,结合CSS等等,这对今后的网页优化有十分重要的启发意义.以下是链接:
图片库最终版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值