【前端学习之路】JavaScript文档对象模型(四)

本文上接【前端学习之路】JavaScript语法(三),主要讲解JavaScript中文档对象模型DOM的概念。
本文部分内容参考W3school中JavaScript模块,在此感谢W3school对本文的支持。W3school主页

文档对象模型(DOM)

DOM::Document Object Model。
通过 HTML DOM,JavaScript 能够访问、更改、添加或删除 HTML 文档的任意元素。

DOM编程界面

编程界面是每个对象的属性和方法。

  • 属性是您能够获取或设置的值(就比如改变 HTML 元素的内容)。
  • 方法是您能够完成的动作(比如添加或删除 HTML 元素)。
    例子:
<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = "Hello World!";
</script>

</body>
</html>

在这个例子中,getElementById是方法,innerHTML是属性。

HTML DOM Document对象

文档对象(document 对象)代表当前网页。
我们通过访问 document 对象,来访问 HTML 页面中的任何元素。
下面是一些如何使用 document 对象来访问和操作 HTML 的实例。
查找HTML元素

方法 描述
document.getElementById(id) 通过元素id来查找HTML中某一元素
document.getElementsByTagName(name) 通过标签名来查找元素
document.getElementsByClassName(name) 通过类名查找元素

因为每个标签的id是唯一的,所以Element不使用复数格式;因为HTML文档中一个标签或者类名可能出现多次,所以使用复数格式Elements;
改变HTML元素

方法 描述
element.innerHTML = new html content 改变元素的 inner HTML
element.attribute = new value 改变 HTML 元素的属性值
element.setAttribute(attribute, value) 改变 HTML 元素的属性值
element.style.property = new style 改变 HTML 元素的样式

添加和删除元素

方法 描述
document.createElement(element) 创建 HTML 元素
document.removeChild(element) 删除HTML 元素
document.appendChild(element) 添加 HTML 元素
document.replaceChild(element) 替换 HTML 元素
document.write(text) 写入 HTML 输出流

添加事件处理程序

方法 描述
document.getElementById(id).onclick = function(){code} 向element对应的onclick事件添加事件处理程序

HTML对象选择器
因为首个 HTML DOM Level 1 (1998)只定义了 11 个 HTML 对象、对象集合和属性。在 HTML DOM Level 3,加入了更多对象、集合和属性。
因为具体对象、集合和属性很多,这里就列举几个经常用的,其余的可以在W3school JavaScript DOM 文档中找到。

属性 描述
document.anchors 返回拥有 name 属性的所有 <a> 元素。
document.body 返回 <body> 元素
document.cookie 返回文档的 cookie
document.documentElement 返回<html> 元素
document.forms 返回所有<form> 元素
document.head 返回 <head> 元素
document.images 返回所有 <img> 元素
document.links 返回拥有 href 属性的所有 <area> 和 <a> 元素
document.scripts 返回所有 <script> 元素

查找HTML元素

通过 id 查找 HTML 元素

var element=document.getElementById("id");

如果元素被找到,此方法会以对象返回该元素。
如果未找到元素,myElement 将包含 null。

通过标签名查找 HTML 元素
查找所有<p>元素:

var x=document.getElementsByTagName("p");

查找id="main"的元素,然后查找"main"中所有<p>元素:

var x=document.getElementById("main");
var y=x.getElementsByTagName("p");

通过类名查找 HTML 元素
如果您需要找到拥有相同类名的所有 HTML 元素,请使用 getElementsByClassName()。
本例返回包含 class=“class” 的所有元素的列表:

var x=document.getElementsByClassName("class");

通过 CSS 选择器查找 HTML 元素
如果您需要查找匹配指定 CSS 选择器的所有 HTML 元素,可以使用 querySelectorAll() 方法。

本例返回 class=“intro” 的所有 <p> 元素列表:

var x = document.querySelectorAll("p.intro");

通过 HTML 对象集合查找 HTML 元素
本例查找 id=“frm1” 的 form 元素,在 forms 集合中,然后显示所有元素值:

var x = document.forms["frm1"];
var text = "";
 var i;
for (i = 0; i < x.length; i++) {
    text += x.elements[i].value + "<br>";
}
document.getElementById("demo").innerHTML = text;

改变HTML

document.write()
在 JavaScript 中,document.write() 可用于直接写入 HTML 输出流:

document.write(Date());

需要注意的是,不要再文档加载后使用document.write()。因为这样做会覆盖原文档。

改变HTML内容
修改 HTML 文档内容最简单的方法是,使用 innerHTML 属性。如需修改 HTML 元素的内容,请使用此语法:

document.getElementById(id).innerHTML = new text

改变属性的值
如需修改 HTML 属性的值,请使用如下语法:

document.getElementById(id).attribute = new value

改变CSS样式

如需更改 HTML 元素的样式,请使用此语法:

document.getElementById(id).style.property = new style

property是你想改变的样式名称,比如说color,font等等。

创建HTML动画

JavaScript 动画是通过对元素样式进行渐进式变化编程完成的。
这种变化通过一个计数器来调用。当计数器间隔很小时,动画看上去就是连贯的。
例子:

<!DOCTYPE html>
<html>
<head>
	<title>HTML动画</title>
	<style type="text/css">
		#container {
		  width: 400px;
		  height: 400px;
		  position: relative;
		  background: yellow;
		}
		#animation {
		  width: 50px;
		  height: 50px;
		  position: absolute;
		  background-color: red;
		}
	</style>
</head>
<body>
	<button onclick="Move();">点我</button>
	<div id="container">
		<div id="animation">
		</div>
	</div>
	<script type="text/javascript">
		function Move(){
			var element=document.getElementById("animation");
			var pos=0;
			var id=setInterval(frame,5);
			function frame(){
				if(pos==350){					//当pos等于350时,使用clearInterval()函数停止计时器对frame的周期执行
					//clearInterval(id)的参数是setInterval()返回的id值,代表在第id次计时器停止执行。
					clearInterval(id);
				}
				else{
					pos++;
					element.style.top=pos+"px";
					element.style.left=pos+"px";
				}
			}
		}
	</script>
</body>
</html>

setInterval(func,interval)是一个计时器,表示每隔interval毫秒执行func函数。计时器的停止函数为clearInterval(id),其中id为setInterval()函数的返回值。

HTML DOM事件

在HTML中,通过事件触发来执行JavaScript的代码或者函数。

事件 作用
onclick 按钮被点击时执行,在button中常用
onload 用户进入界面会触发onload事件,在body中常用
onunload 用户离开界面会触发onunload事件,在body中常用
onchange 经常与输入字段验证结合使用,用户改变输入内容时触发,在input中常用
onmouseover 用户将鼠标移至 HTML 元素上时触发事件
onmouseout 用户将鼠标移出 HTML 元素时触发事件
onmousedown 鼠标按钮被点击时触发事件
onmousedown 鼠标按钮被释放时触发事件
onfocus 事件在对象获得焦点时触发,常用于input文本框
onblur 事件会在对象失去焦点时触发,常用于input文本框

HTML DOM事件监听程序

我们在js中通过addEventListener() 方法为指定DOM元素添加事件监听器。也可以通过removeEventListener() 方法轻松地删除事件监听器。能被事件监听程序监听到的事件可看这篇博客:
JS中addEventListener的用法

语法

添加事件:addEventListener()

element.addEventListener(event,myfunction,useCapture)

第一个参数event是事件的类型(例如"click"或"focus",事件名去掉"on")。此参数必选。
第二个参数myfunction是当事件发生时我们需要调用的函数。此参数必选。
第三个参数useCapture,是一个布尔值,指定使用时间冒泡还是时间捕获。此参数可选。
移除事件:removeEventListener()

element.removeEventListener(event, myfunction);

这两个参数和添加事件的前两个参数一致,用于删除某个DOM元素上监听的事件。

向元素添加事件处理

例:

document.getElementById("id").addEventListener("click",function(){console.log("Hello");});

也可以引用外部“命名”函数:

document.getElementById("id").addEventListener("click",myfunction);

function myfunction(){
	console.log("Hello");
}

向相同元素添加多个事件处理程序

addEventListener() 方法允许您向相同元素添加多个事件,同时不覆盖已有事件:
对相同元素、相同事件添加不同函数,例:

element.addEventListener("click", myFunction);
element.addEventListener("click", mySecondFunction);

同时,也可以相同元素、不同事件添加函数:

element.addEventListener("mouseover", myFunction);
element.addEventListener("click", mySecondFunction);
element.addEventListener("mouseout", myThirdFunction);

向window对象添加事件处理程序

addEventListener() 允许您将事件监听器添加到任何 HTML DOM 对象上,比如 HTML 元素、HTML 对象、window 对象或其他支持事件的对象,比如 xmlHttpRequest 对象。

例,当用户调整窗口大小时触发的事件监听器:

window.addEventListener("resize", function(){

document.getElementById("demo").innerHTML = sometext;
});

传递参数

当传递参数值时,请以参数形式使用调用指定函数的“匿名函数”:

例:

element.addEventListener("click", function(){ myFunction(p1, p2); });

事件冒泡传播or事件捕获传播

在 addEventListener() 方法中,我们使用useCapture参数规定传播类型。默认值是 false,将使用冒泡传播,如果该值设置为 true,则事件使用捕获传播。
事件冒泡传播
最内侧元素的事件会首先被处理,然后是更外侧的:首先处理 <p> 元素的点击事件,然后是 <div> 元素的点击事件。
事件捕获传播
最外侧元素的事件会首先被处理,然后是更内侧的:首先处理 <div> 元素的点击事件,然后是 <p> 元素的点击事件。

removeEventListener() 方法

removeEventListener() 方法会删除已通过 addEventListener() 方法附加的事件处理程序:
例:

element.removeEventListener("mousemove", myFunction);

HTML DOM导航节点树

DOM节点

根据 W3C HTML DOM 标准,HTML 文档中的所有事物都是节点:

  • 整个文档是文档节点
  • 每个 HTML 元素是元素节点
  • HTML 元素内的文本是文本节点
  • 每个 HTML 属性是属性节点
  • 所有注释是注释节点

有了 HTML DOM,节点树中的所有节点都能通过 JavaScript 访问。JavaScript能够创建新节点,还可以修改和删除所有节点。

节点关系

通过 JavaScript,您可以使用以下节点属性在节点之间导航:

  • parentNode 父节点
  • childNodes 返回一个节点的所有子节点集合
  • childNodes[nodenumber] 第nodenumber个子节点
  • firstChild 第一个子节点
  • lastChild 最后一个子节点
  • nextSibling 相邻的下一个子节点
  • previousSibling 相邻的上一个子节点

子节点和节点值
DOM 处理中的一种常见错误是认为元素节点中包含文本。

实例:

<title id="demo">DOM 教程</title> 

上面例子中的元素节点 <title> 不包含文本。它包含了值为 “DOM 教程” 的文本节点,同时也包含了属性节点,它本身是元素节点。
文本节点的值能够通过节点的 innerHTML 属性进行访问:

var myTitle = document.getElementById("demo").innerHTML;

访问 innerHTML 属性等同于访问首个子节点的 nodeValue:

var myTitle = document.getElementById("demo").firstChild.nodeValue;

也可以这样访问第一个子节点:

var myTitle = document.getElementById("demo").childNodes[0].nodeValue;

DOM根节点

有两个特殊属性允许访问完整文档:

  • document.body 文档的 body
  • document.documentElement 整个文档内容

nodeName属性

nodeName 属性规定节点的名称。

  • nodeName 是只读的
  • 元素节点的 nodeName 等同于标签名
  • 属性节点的 nodeName 是属性名称
  • 文本节点的 nodeName 总是 #text
  • 文档节点的 nodeName 总是 #document

nodeValue 属性

nodeValue 属性规定节点的值。

  • 元素节点的 nodeValue 是 undefined
  • 文本节点的 nodeValue 是文本内容
  • 属性节点的 nodeValue 是属性值

添加和删除节点

创建新HTML节点(元素)

我们通过一个例子来了解创建节点的过程:

<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另一个段落。</p>
</div>

<script>
//创建<p>元素节点
var para = document.createElement("p");
//创建文本节点
var node = document.createTextNode("这是新文本。");
//将文本节点挂在元素节点上,作为元素节点的子节点
para.appendChild(node);

var element = document.getElementById("div1");
element.appendChild(para);
</script>

结果:
在这里插入图片描述
使用appendChild(element)函数,追加新节点作为父节点的最后一个子节点。我们也可以使用insertBefore(element) 方法向父节点添加节点,不过追加新节点将作为父节点的第一个子节点。
例子:
我们将上面的element.appendChild(para);换成element.insertBefore(para, child);,将得到如下结果:
在这里插入图片描述

删除HTML节点(元素)

如需删除某个 HTML 节点,您需要知晓该节点的父节点:

<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另一个段落。</p>
</div>

<script>
//获得待删除节点的父节点
var parent = document.getElementById("div1");
//获得待删除节点
var child = document.getElementById("p1");
//通过父节点删除子节点
parent.removeChild(child);
</script>

能够在不引用父的情况下删除某个节点是极好的。但是很遗憾。DOM 需要同时了解您需要删除的节点及其父节点。
这是一种常见的解决方法:找到你想要删除的子节点,并利用其 parentNode 属性找到父节点:

var child = document.getElementById("p1");
child.parentNode.removeChild(child);

替换HTML节点(元素)

如需替换元素的,请使用 replaceChild() 方法,这个方法同样需要得到待替换节点的父元素,才能进行替换。

<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另一个段落。</p>
</div>

<script>
var para = document.createElement("p");
var node = document.createTextNode("这是新文本。");
para.appendChild(node);

var parent = document.getElementById("div1");
var child = document.getElementById("p1");
parent.replaceChild(para, child);
</script>

结果:
在这里插入图片描述

HTML DOM 集合与节点列表

HTMLCollection 对象

在前面我们就学到,可以使用getElementsByTagName() 方法返回 HTMLCollection 对象。
HTMLCollection 对象是类数组的 HTML 元素列表(集合)。
下面的代码选取文档中的所有 <p> 元素:

var x = document.getElementsByTagName("p");

该集合中的元素可通过索引号进行访问。
如需访问第二个 <p> 元素,我们可以使用x[1]代表。也可以通过标签的名称和id号来获得对应元素。

除此之外,我们可以通过HTMLCollection 对象的length属性获得HTMLCollection中元素的数量。

需要注意的是,HTMLCollection 并非数组!
HTMLCollection 也许看起来像数组,但并非数组。我们能够遍历列表并通过数字引用元素(就像数组那样)。不过,我们无法对 HTMLCollection 使用数组方法,比如 valueOf()、pop()、push() 或 join()。

NodeList对象

NodeList 对象是从文档中提取的节点列表(集合)。和HTMLCollection几乎相同,一般由不同方法返回不同类型。

  • 所有浏览器都会为 childNodes 属性返回 NodeList 对象。
  • 如使用 getElementsByClassName() 方法,某些(老的)浏览器会返回 NodeList 对象而不是 HTMLCollection。
  • 大多数浏览器会为 querySelectorAll() 方法返回 NodeList 对象。

和HTMLCollection对象一样,我们可以通过length属性获得NodeList的长度,也可以通过索引像数组那样访问每个元素,但是不能通过id和名称获取。

只有 NodeList 对象能包含属性节点和文本节点。
需要注意的是,NodeList并非数组!
和HTMLCollection一样,NodeList也许看起来像数组,但并非数组。我们能够遍历NodeList并通过数字引用元素。不过,我们无法对 NodeList使用数组方法,比如 valueOf()、pop()、push() 或 join()。

发布了61 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41427568/article/details/103266564