JavaScript的DOM编程:基本介绍,js代码应在的位置和基本使用

基本介绍

DOM:Document Object Model(文本对象模型)
D:文档 – html 文档 或 xml 文档
O:对象 – document 对象的属性和方法
M:模型 
DOM 是针对xml(html)的基于树的API。
DOM树:节点(node)的层次。
DOM 把一个文档表示为一棵家谱树(父,子,兄弟)
DOM定义了Node的接口以及许多种节点类型来表示XML节点的多个方面

js代码应在的位置和基本使用

最终应该写的位置

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
	//当整个HTML完全加载成功后触发window.onload事件
	//事件触发时就会执行后面的function里面的函数体
	window.onload=function()
	{
		//获取所有的button节点,然后获取第一个元素
		var btn=document.getElementsByTagName("button")[0];
		//为button的onlick事件赋值,点击button的时候会执行下面的函数体
		btn.onclick=function()
		{
			alert("hello");
		}
	}
</script>
</head>
<body>
	<button>点击</button>
</body>
</html>

之前错误的尝试

我们想直接在 html 页面中书写代码
<button id="button" onclick="alert('hello');">点击</button>
缺点: 
	js 和 html 强耦合, 不利用代码的维护
	 若 click 相应函数是比较复杂的, 则需要先定义一个函数, 
	 然后再在 onclick 属性中完成对函数的引用, 比较麻烦
一般不能在 body 节点之前来直接获取 body 内的节点,
此时 html 文档树还没有加载完成, 
 获取不到指定的节点:
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>xx</title>
	<script type="text/javascript">
		var cityNode = document.getElementById("city");
		//打印结果为 null.
		alert(cityNode);
	</script>
</head>
<body>
.......
在整个 html 文档的最后编写类似代码, 但这不符合习惯
最后在 body 节点之前编写 js 代码, 但需要利用 window.onload 事件, 
该事件在当前文档完全加载之后被触发, 所以其中的代码可以获取到当前文档的任何节点.

对应的API

getElementById() 
寻找一个有着给定 id 属性值的元素,返回值是一个有着给定 id 属性值的元素节点。
如果不存在这样的元素,它返回 null。

getElementsByTagName()
寻找有着给定标签名的所有元素,这个方法将返回一个节点集合,这个集合可以当作一个数组来处理。
这个集合的 length 属性等于当前文档里有着给定标签名的所有元素的总个数。
该方法不必非得用在整个文档上。它也可以用来在某个特定元素的子节点当中寻找有着给定标签名的元素。

hasChildNodes()	
该方法用来检查一个元素是否有子节点,返回值是 truefalse.
var booleanValue = element.hasChildNodes();
文本节点和属性节点不可能再包含任何子节点,
所以对这两类节点使用 hasChildNodes 方法的返回值永远是 false.
如果 hasChildNodes 方法的返回值是 false,
则 childNodes,firstChild,lastChild 将是空数组和空字符串。

文档里的每个节点都有以下属性。
nodeName:一个字符串,其内容是给定节点的名字。
var name = node.nodeName;
如果给定节点是一个元素节点或属性节点,nodeName 属性将返回这个元素的名字。
如果给定节点是一个文本节点,nodeName 属性将返回内容为 #text 的字符串。
nodeName 是一个只读属性。

nodeType:返回一个整数,这个数值代表着给定节点的类型。

nodeValue:返回给定节点的当前值(字符串)
如果给定节点是一个属性节点,返回值是这个属性的值。
如果给定节点是一个文本节点,返回值是这个文本节点的内容。
如果给定节点是一个元素节点,返回值是 null
nodeValue 是一个 读/写 属性,但不能对元素节点的nodeValue属性设置值,
但可以为文本节点的 nodeValue 属性设置一个值。

replaceChild()
把一个给定父元素里的一个子节点替换为另外一个子节点
var reference = element.replaceChild(newChild,oldChild);
返回值是一个指向已被替换的那个子节点的引用指针。
如果被插入的子节点还有子节点,则那些子节点也被插入到目标节点中

getAttribute()
返回一个给定元素的一个给定属性节点的值
var attributeValue = element.getAttribute(attributeName);
给定属性的名字必须以字符串的形式传递给该方法。
给定属性的值将以字符串的形式返回,如果给定属性不存在,getAttribute() 将返回一个空字符串.

setAttribute()
将给定元素节点添加一个新的属性值或改变它的现有属性的值。
element.setAttribute(attributeName,attributeValue);
属性的名字和值必须以字符串的形式传递给此方法
如果这个属性已经存在,它的值将被刷新;如果不存在,setAttribute()方法将先创建它再为其赋值。

createElement()
按照给定的标签名创建一个新的元素节点。方法只有一个参数:将被创建的元素的名字,是一个字符串.
var reference = document.createElement(element);
方法的返回值:是一个指向新建节点的引用指针。
返回值是一个元素节点,所以它的 nodeType 属性值等于 1。
新元素节点不会自动添加到文档里,新节点没有 nodeParent 属性,
它只是一个存在于 JavaScript 上下文的对象.

createTextNode()
创建一个包含着给定文本的新文本节点。这个方法的返回值是一个指向新建文本节点引用指针。
var reference = document.createTextNode(text);
方法只有一个参数:新建文本节点所包含的文本字符串
方法的返回值:是一个指向新建节点的引用指针。它是一个文本节点,所以它的 nodeType 属性等于 3.
新元素节点不会自动添加到文档里,新节点没有 nodeParent 属性

appendChild()
为给定元素增加一个子节点:                                   
var reference = element.appendChild(newChild).              
给定子节点 newChild 将成为给定元素节点 element 的最后一个子节点。
方法的返回值是一个指向新增子节点的引用指针。
该方法通常与 createElement() createTextNode() 配合使用

insertBefore()
把一个给定节点插入到一个给定元素节点的给定子节点的前面
var reference =  element.insertBefore(newNode,targetNode);
节点 newNode 将被插入到元素节点 element 中并出现在节点 targetNode 的前面.
节点 targetNode 必须是 element 元素的一个子节点。
该方法通常与 createElement()createTextNode() 配合使用

removeChild()
从一个给定元素里删除一个子节点
var reference = element.removeChild(node);
返回值是一个指向已被删除的子节点的引用指针。
某个节点被 removeChild() 方法删除时,这个节点所包含的所有子节点将同时被删除。
如果想删除某个节点,但不知道它的父节点是哪一个,parentNode 属性可以帮忙。

ChildNodes:返回一个数组,这个数组由给定元素节点的子节点构成:
var nodeList = node.childNodes;
文本节点和属性节点都不可能再包含任何子节点,所以它们的 ChildNodes 属性永远会返回一个空数组。
如果想知道某个元素有没有子节点,可以用 hasChildNodes 方法。
如果想知道某个元素有多少个子节点,可以用 childNodes 数组的 length 属性。
childNodes 属性是一个只读属性。

firstChild:该属性返回一个给定元素节点的第一个子节点,返回这个节点对象的指针。
var reference = node.firstChild;
文本节点和属性节点都不可能包含任何子节点,所以它们的 firstChild 属性永远会返回 null。
某个元素的 firstChild 属性等价于这个元素的 childNodes 节点集合中的第一个节点,即:
var reference = node.ChildNodes[0];
firstChild 属性是一个只读属性。

lastChild:对应 firstChild 的一个属性。
nextSibling: 返回一个给定节点的下一个子节点。
parentNode:返回一个给定节点的父节点。
parentNode 属性返回的节点永远是一个元素节点,因为只有元素节点才有可能包含子节点。
document 节点的没有父节点。
previousSibling:返回一个给定节点的上一个子节点

innerHTML属性
利用这个节点的innerHTML属性,可以获取这个节点里面的所有的HTML内容
还可以利用这个来修改这个节点里面的HTML的内容

练习

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title></title>
		
		<script type="text/javascript">
			window.onload = function(){
				//点击每个 li 节点, 都弹出其文本值. 
				//1. 获取所有的 li 节点
				var liNodes = document.getElementsByTagName("li");
				
				//2. 实用 for 循环进行遍历. 得到每一个 li 节点
				for(var i = 0; i < liNodes.length; i++){
					//3 为每一个 li 节点添加 onclick 响应函数. 
					liNodes[i].onclick = function(){
						//4. 在响应函数中获取当前节点的文本节点的文本值
						//5. alert 打印. 
						//this 为正在响应事件的那个节点. 
						alert(this.firstChild.nodeValue);
						
						//alert(liNodes[i].firstChild.nodeValue);为什么不可以这样写?
						//开始执行这个for循环的时候,i的确的对应节点的下标
						//但是我们点击这个节点的时候,for循环早就执行完毕,i已经是8
						//此时 i 已经是 8 了, 而 liNodes[8] 不指向任何节点.
						//alert(i);
					}
				}
			}
		</script>
	</head>
	<body>
		<p>你喜欢哪个城市?</p>
		<ul id="city">
			<li id="bj" name="BeiJing">北京</li>
			<li>上海</li>
			<li>东京</li>
			<li>首尔</li>
		</ul>
		<br><br>
		<p>你喜欢哪款单机游戏?</p>
		<ul id="game">
			<li id="rl">红警</li>
			<li>实况</li>
			<li>极品飞车</li>
			<li>魔兽</li>
		</ul>
		<br><br>
		name: <input type="text" name="username" 
			id="name" />
	</body>
</html>	

angularjs插件

发现编写js代码的时候没有提示,所以就安装了这个插件,有提示舒服多了
angularjs插件

创建节点练习

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title></title>
		
		<script type="text/javascript">
			/* 
				需求: 点击 submit 按钮时, 检查是否选择 type, 
				若没有选择给出提示: "请选择类型"; 
		
				检查文本框中是否有输入(可以去除前后空格), 
				若没有输入,则给出提示: "请输入内容";
				
				若检查都通过, 则在相应的 ul 节点中添加对应的 li 节点 
				
				步骤:
					1.先是获取对应的按钮submit,为她添加onclick响应函数
					2.在onclick响应函数的结尾处添加return false,
						这样可以取消提交按钮的默认行为
					3.检查是否选择了type,若没有选择就提示选择类型,
						这里先是选择所有的name="type"的节点types,
						然后遍历types,检查其中的type的checked属性是否存在
						因为checked属性存在就可以代表选择了这个属性,无论它的值是什么
						都是选择了这个属性
						
						怎么判断checked存在呢?通过if(元素节点.属性名)来判断就行
					若是没有任何一个type被选中,就提示要选择类型然后响应方法结束,return false;
					
					否则就获取name="name"的文本值,定义为nameValue
					取出nameValue前后空格,然后和""进行比较,看看是不是只是输入了空格
					若是就提示输入内容,方法结束
					否则直接创建li节点,创建nameValue的文本节点,添加到对应的ul的子节点
			*/
			window.onload = function()
			{
				var submit =document.getElementById("submit");
				submit.onclick = function()
				{
					var types =document.getElementsByName("type");
					var typeVal=null;
					for(var i=0;i<types.length;i++)
					{
						if(types[i].checked)
						{
							typeVal=types[i].value;
							break;
						}
					}
					if(typeVal == null)
					{
						alert("选择类型");
						return false;
					}
					var nameEle=document.getElementsByName("name")[0];
					var nameVal=nameEle.value;
					
					var reg=/^\s*|\s*$/g;
					nameVal=nameVal.replace(reg,"");
					nameEle.value=nameVal;
					
					if(nameVal=="")
					{
						alert("输入内容");
						return false;
					}
					var li =document.createElement("li");
					var content=document.createTextNode(nameVal);
					
					li.appendChild(content);
					document.getElementById(typeVal).appendChild(li);
					return false;
				}
			}
		</script>
	</head>
	<body>
		<p>你喜欢哪个城市?</p>
		<ul id="city">
			<li id="bj" name="BeiJing">北京</li>
			<li>上海</li>
			<li>东京</li>
			<li>首尔</li>
		</ul>
		<br><br>
		<p>你喜欢哪款单机游戏?</p>
		<ul id="game">
			<li id="rl">红警</li>
			<li>实况</li>
			<li>极品飞车</li>
			<li>魔兽</li>
		</ul>
		<br><br>
	<form action="xx.html" name="myform">
		<input type="radio" name="type" value="city">城市 
		<input type="radio" name="type" value="game">游戏 
		name: <input type="text" name="name" /> 
		<input type="submit" value="Submit" id="submit" />
	</form>
</body>
</html>	

节点替换

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
	//需求: 为所有的 li 节点添加 onclick 响应函数
	//实现 city 子节点和 game 子节点对应位置的元素的互换

	window.onload = function() 
	{
		//定义一个互相交换节点的函数
		function exchangeEach(aNode,bNode) 
		{
			var aParent = aNode.parentNode;
			var bParent = bNode.parentNode;
			if(aParent && bParent)
			{
				//克隆aNode,因为bParent.replaceChild(aNode, bNode);
				//把一个给定父元素里的一个子节点替换为另外一个子节点
				//返回值是一个指向已被替换的那个子节点的引用指针(就是旧的节点)
				//那么我们再想将aParent.replaceChild(bNode, aNode);
				//这时候a已经不见了的,因为在换的过程中也会将新的节点从原来的位置删除掉

				var aNode2=aNode.cloneNode(true);
				//将aNode的onclick事件也复制了
				aNode2.onclick = aNode.onclick;
				//将我们用来标志的index也复制了
				aNode2.index = aNode.index;
				
				bParent.replaceChild(aNode2, bNode);
				aParent.replaceChild(bNode, aNode);
			}
		}
		//1.获取所有的li节点
		var liNodes = document.getElementsByTagName("li");
		//2.给每一个li节点添加onclick函数
		for(var i=0;i<liNodes.length;i++)
		{
			//手动为每一个li节点添加index属性,因为到点击后i的值一直是8,使用i获取不到节点
			liNodes[i].index=i;
			liNodes[i].onclick = function () 
			{
					var targetIndex=0;
					if(this.index<4)
					{
						targetIndex =4+this.index;
					}
					else
					{
						targetIndex = this.index-4;
					}
					//这里要将表示数组的index进行交换
					//不然交换一次后就交换不了了,因为
					//如果没有交换index第二次点击就是自己跟自己交换了
					//比如1和5交换后,数组的1位置是index5,5的位置是index1
					//那么第二次点击的时候,1位置想要和数组的targetIndex位置交换
					//经过换算,targetIndex的值就是1
					var tempIndex=this.index;
					this.index= liNodes[targetIndex].index;
					liNodes[targetIndex].index=tempIndex;
					
					exchangeEach(this, liNodes[targetIndex]);
			}
		}
	}
</script>
</head>
<body>
	<p>你喜欢哪个城市?</p>
	<ul id="city">
		<li id="bj">北京</li>
		<li>上海</li>
		<li>东京</li>
		<li>首尔</li>
	</ul>
	<br><br>
	<p>你喜欢哪款单机游戏?</p>
	<ul id="game">
		<li id="rl">红警</li>
		<li>实况</li>
		<li>极品飞车</li>
		<li>魔兽</li>
	</ul>
	<br><br>
	<form action="dom-7.html" name="myform">
		<input type="radio" name="type" value="city">城市 <input
			type="radio" name="type" value="game">游戏 name: <input
			type="text" name="name" /> <input type="submit" value="Submit"
			id="submit" />
	</form>
</body>
</html>

由insertBefore()编写insertAfter

<script type="text/javascript">
	//把newNode插入到refNode的后面
	function InsertAfter(newNode ,refNode ) 
	{
		//1.首先判断refNode是否是其父节点的最后一个节点
		//2.如果是就好办了,直接将newNode添加到refNode父节点的最后一个子节点
		//3.如果不是就要获取refNode的下一个兄弟节点,
		//	然后将newNode插入到下一个兄弟节点的前面,
		//为什么这样多此一举呢?因为JDK里面只提供insertBefore的方法
		var parentNode=refNode.parentNode;
		if(parentNode)
		{
			var lastNode = parentNode.lastChild;
			if(refNode==lastNode)
			{
				parentNode.appendChild(newNode);
			}
			else
			{
				var nextNode=refNode.nextSibling;
				parentNode.insertBefore(newNode, nextNode);
			}
		}
	}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReflectMirroring

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值