【前端学习之路】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()。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值