js教程(9)-- HTML DOM
2019.9.28:
学习内容:
HTML DOM 方法是您能够(在 HTML 元素上)执行的动作。
HTML DOM 属性是您能够设置或改变的 HTML 元素的值。
函数学习:
(1)setInterval(func, delay); 重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。可用于做动画
delay: 毫秒级
(2) clearInterval()
方法可取消先前通过 setInterval()
设置的重复定时任务。
特殊对象学习:
(1) 只读对象 Navigator
接口 : 表示用户代理的状态和标识。 它允许脚本查询它和注册自己进行一些活动。
navigator.cookieEnable: 返回布尔值以表明cookies是否能再浏览器中启用
一、了解 DOM:
DOM:文档对象模型
通过 HTML DOM,JavaScript 能够访问和改变 HTML 文档的所有元素。
通过这个对象模型,JavaScript 获得创建动态 HTML 的所有力量:
DOM中,一切HTML元素都是对象:那就有属性和方法
属性是您能够获取或设置的值(就比如改变 HTML 元素的内容)。
方法是您能够完成的动作(比如添加或删除 HTML 元素)。
HTML DOM 是 HTML 的标准对象模型和编程接口。它定义了:
- 作为对象的 HTML 元素
- 所有 HTML 元素的属性
- 访问所有 HTML 元素的方法
- 所有 HTML 元素的事件
换言之:HTML DOM 是关于如何获取、更改、添加或删除 HTML 元素的标准。
举个例子:
<html>
<body>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = "Hello World!";
</script>
</body>
</html>
getElementById 方法
访问 HTML 元素最常用的方法是使用元素的 id。
在上面的例子中,getElementById 方法使用 id="demo" 来查找元素。
innerHTML 属性
获取元素内容最简单的方法是使用 innerHTML 属性。
innerHTML 属性可用于获取或替换 HTML 元素的内容。
innerHTML 属性可用于获取或改变任何 HTML 元素,包括 <html> 和 <body>。
二、DOM 方法:
1)查找 HTML 元素:
document.
getElementBy Id() : 通过id查找元素
TagName() : 通过标签名
ClassName() : 通过类名
querySelectorAll("p.intro") : 查找匹配指定 CSS 选择器(id、类名、类型、属性、属性值等等)的所有 HTML 元素
2)添加和删除元素:
document.
createElement(element) : 创建HTML元素
removeChild(element) : 删除HTML元素
appendChild(element) : 添加 HTML元素
replaceChild(element) : 替换 HTML元素
write(text) : 写入 HTML 输出流
注意:千万不要在文档加载后使用 document.write()。这么做会覆盖文档。
3) 查找 HTML 对象
三、DOM 属性:
1)改变 HTML元素:
element.
2) 添加事件处理程序:
HTML DOM 允许您在事件发生时执行代码。
当“某些事情”在 HTML 元素上发生时,浏览器会生成事件:
- 点击某个元素时
- 页面加载时
- 输入字段被更改时
四、DOM 事件:
(1) 🌰:
HTML 事件的例子:
- 当用户点击鼠标时
- 当网页加载后
- 当图像加载后
- 当鼠标移至元素上时
- 当输入字段被改变时
- 当 HTML 表单被提交时
- 当用户敲击按键时
举例:点击事件(分配了onclick事件就能使用事件属性)
<body> <h1 onclick="changeText(this)">点击此文本!</h1> <script> function changeText(id) { id.innerHTML = "Hello:)"; } </script> </body>
(2) onload 和 onunload 事件
当用户进入后及离开页面时,会触发 onload 和 onunload 事件。
onload 事件可用于检测访问者的浏览器类型和浏览器版本,然后基于该信息加载网页的恰当版本。
onload 和 onunload 事件可用于处理 cookie。
只读对象 Navigator
接口 : 表示用户代理的状态和标识。 它允许脚本查询它和注册自己进行一些活动。
<body onload="checkCookies()"> <p id="demo"></p> <script> function checkCookies() { var text = ""; if (navigator.cookieEnabled == true) { text = "Cookie 已启用"; } else { text = "Cookie 未启用"; } document.getElementById("demo").innerHTML = text; } </script> </body>
(3) onchange 事件
onchange 事件经常与输入字段验证结合使用。
下面是一个如何使用 onchange 的例子。当用户改变输入字段内容时,会调用 upperCase() 函数。
<head> <script> function myFunction() { var x = document.getElementById("fname"); x.value = x.value.toUpperCase(); } </script> </head> <body> 请输入您的名字:<input type="text" id="fname" onchange="myFunction()"> <p>离开输入字段时,会触发一个函数,将输入文本转换为大写。</p> </body>
(4) onmouseover 和 onmouseout 事件(mOver, mOut; mDown, mUp)
onmouseover 和 onmouseout 事件可用于当用户将鼠标移至 HTML 元素上或移出时触发某个函数:
<html> <body> <div onmouseover="mOver(this)" onmouseout="mOut(this)" style="background-color:#D94A38;width:120px;height:20px;padding:40px;"> 请把鼠标移上来</div> <script> function mOver(obj) { obj.innerHTML = "谢谢您" } function mOut(obj) { obj.innerHTML = "请把鼠标移上来" } </script> </body>
综合应用:onmousedown, onmouseup 以及 onclick 事件
onmousedown, onmouseup 以及 onclick 事件构成了完整的鼠标点击事件。
首先当鼠标按钮被点击时,onmousedown 事件被触发;然后当鼠标按钮被释放时,onmouseup 事件被触发;最后,当鼠标点击完成后,onclick 事件被触发。
<body> <div onmousedown="mDown(this)" onmouseup="mUp(this)" style="background-color:#D94A38;width:90px;height:20px;padding:40px;"> 点击鼠标</div> <script> function mDown(obj) { obj.style.backgroundColor = "#1ec5e5"; obj.innerHTML = "松开鼠标"; } function mUp(obj) { obj.style.backgroundColor="#D94A38"; obj.innerHTML="谢谢您"; } </script> </body>
五、DOM 事件监听器
addEventListener() 方法 添加当用户点击按钮时触发的事件监听器
addEventListener() 方法为指定元素指定事件处理程序。为元素附加事件处理程序而不会覆盖已有的事件处理程序。
您能够向一个元素添加多个事件处理程序。
您能够向一个元素添加多个相同类型的事件处理程序,例如两个 "click" 事件。
您能够向任何 DOM 对象添加事件处理程序而非仅仅 HTML 元素,例如 window 对象。
addEventListener() 方法使我们更容易控制事件如何对冒泡作出反应。
当使用 addEventListener() 方法时,JavaScript 与 HTML 标记是分隔的,已达到更佳的可读性;即使在不控制 HTML 标记时也允许您添加事件监听器。
您能够通过使用 removeEventListener() 方法轻松地删除事件监听器。
语法:
element.addEventListener(event, function, useCapture);
第一个参数是事件的类型(比如 "click" 或 "mousedown")。
第二个参数是当事件发生时我们需要调用的函数。
第三个参数是布尔值,指定使用事件冒泡还是事件捕获。此参数是可选的。
注意:请勿对事件使用 "on" 前缀;请使用 "click" 代替 "onclick"。
事件冒泡还是事件捕获?
在 HTML DOM 中有两种事件传播的方法:冒泡和捕获。
事件传播是一种定义当发生事件时元素次序的方法。假如 <div> 元素内有一个 <p>,然后用户点击了这个 <p> 元素,应该首先处理哪个元素“click”事件?
在冒泡中,最内侧元素的事件会首先被处理,然后是更外侧的:首先处理 <p> 元素的点击事件,然后是 <div> 元素的点击事件。
在捕获中,最外侧元素的事件会首先被处理,然后是更内侧的:首先处理 <div> 元素的点击事件,然后是 <p> 元素的点击事件。
在 addEventListener() 方法中,你能够通过使用“useCapture”参数来规定传播类型:默认值是 false,将使用冒泡传播,如果该值设置为 true,则事件使用捕获传播。
六、DOM 导航:使用节点关系来导航节点树
根据 W3C HTML DOM 标准,HTML 文档中的所有事物都是节点:
- 整个文档是文档节点
- 每个 HTML 元素是元素节点
- HTML 元素内的文本是文本节点
- 每个 HTML 属性是属性节点
- 所有注释是注释节点
有了 HTML DOM,节点树中的所有节点都能通过 JavaScript 访问。
能够创建新节点,还可以修改和删除所有节点。
节点关系:
节点树中的节点彼此之间有一定的等级关系。
- 术语(父、子和同胞,parent、child 以及 sibling)用于描述这些关系。
- 在节点树中,顶端节点被称为根(根节点)。
- 每个节点都有父节点,除了根(根节点没有父节点)。
- 节点能够拥有一定数量的子
- 同胞(兄弟或姐妹)指的是拥有相同父的节点。
在节点之间导航:
通过 JavaScript,您可以使用以下节点属性在节点之间导航:
- parentNode
- childNodes[nodenumber]
- firstChild
- lastChild
- nextSibling
- previousSibling
文本节点:
DOM 处理中的一种常见错误是认为元素节点中包含文本。
<title id="demo">DOM 教程</title>
元素节点 <title> 不包含文本。它包含了值为 "DOM 教程" 的文本节点,以下3种方式等价:
(1)文本节点的值能够通过节点的 innerHTML 属性进行访问:
var myTitle = document.getElementById("demo").innerHTML;
(2)访问 innerHTML 属性等同于访问首个子节点的 nodeValue:
var myTitle = document.getElementById("demo").firstChild.nodeValue;
(3)也可以这样访问第一个子节点:
var myTitle = document.getElementById("demo").childNodes[0].nodeValue;
特殊:DOM 根节点
有两个特殊属性允许访问完整文档:
- document.body - 文档的 body
- 会把body的html都获取
-
<html> <body> <p>Hello World!</p> <div> <p>DOM 很有用!</p> <p>本例演示 <b>document.body</b> 属性。</p> </div> <script> alert(document.body.innerHTML); </script> </body> </html>
- document.documentElement - 完整文档(html)
nodeName 属性:
nodeName 属性规定节点的名称。
- nodeName 是只读的
- 元素节点的 nodeName 等同于标签名,例如<P>, <H1>
- 属性节点的 nodeName 是属性名称
- 文本节点的 nodeName 总是 #text
- 文档节点的 nodeName 总是 #document
注释:nodeName 总是包含 HTML 元素的大写标签名
nodeValue 属性
nodeValue 属性规定节点的值。
- 元素节点的 nodeValue 是 undefined
- 文本节点的 nodeValue 是文本文本
- 属性节点的 nodeValue 是属性值
nodeType 属性
nodeType 属性返回节点的类型。nodeType 是只读的。
例子: 如下代码显示是: 1
<!DOCTYPE html> <html> <body> <h1 id="id01">我的第一张网页</h1> <p id="id02"></p> <script> document.getElementById("id02").innerHTML = document.getElementById("id01").nodeType; </script> </body> </html>
七:DOM 元素(节点)
(1)创建新 HTML 元素(节点)
如需向 HTML DOM 添加新元素,您必须首先创建这个元素(元素节点),然后将其追加到已有元素。
🌰:
<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 element = document.getElementById("div1"); element.appendChild(para); </script>
效果:
这是一段文字。
这是另一段文字。
这是新的文本。
(2)创建新 HTML 元素 - insertBefore()
前面例子中的 appendChild() 方法,追加新元素作为父的最后一个子。
除此之外您还可以使用 insertBefore() 方法:
<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 element = document.getElementById("div1"); var child = document.getElementById("p1"); element.insertBefore(para, child); </script>
效果:
这是新的文本。
这是一段文字。
这是另一段文字。
(3)删除已有 HTML 元素:
方法 node.remove() 是在 DOM 4 规范中实现的。
但是由于糟糕的浏览器支持,不应该使用该方法。
如需删除某个 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);
(4)替换 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>
效果:
这是新的文本。
这是另一段文字。
八、DOM 集合:
getElementsByTagName() 方法返回 HTMLCollection 对象。
但是collection 对象不是JS数组!!
HTMLCollection 也许看起来像数组,但并非数组。
您能够遍历列表并通过数字引用元素(就像数组那样)。
不过,您无法对 HTMLCollection 使用数组方法,比如 valueOf()、pop()、push() 或 join()
HTMLCollection 对象是类数组的 HTML 元素列表(集合)。
var x = document.getElementsByTagName("p"); y = x[1]; // 访问第二个元素 document.getElementById("demo").innerHTML = x.length; // 返回集合的长度 for (i = 0; i < myCollection.length; i++) { x[i].style.backgroundColor = "red"; } // 改变所有 <p> 元素的背景色
九、DOM 节点列表(NodeList):
它也不是JS 数组!!
HTML DOM NodeList 对象
NodeList 对象是从文档中提取的节点列表(集合)。
NodeList 对象与 HTMLCollection 对象几乎相同。
如使用 getElementsByClassName() 方法,某些(老的)浏览器会返回 NodeList 对象而不是 HTMLCollection。
所有浏览器都会为 childNodes 属性返回 NodeList 对象。
大多数浏览器会为 querySelectorAll() 方法返回 NodeList 对象。
var myNodeList = document.querySelectorAll("p"); y = myNodeList[1]; // 同DOM 集合 document.getElementById("demo").innerHTML = myNodelist.length;
集合和节点列表看似相似,区别:
- HTMLCollection 是 HTML 元素的集合。
- NodeList 是文档节点的集合。
- NodeList 和 HTML 集合几乎完全相同。
- HTMLCollection 和 NodeList 对象都是类数组的对象列表(集合)。
- 它们都有定义列表(集合)中项目数的 length 属性。
- 它们都可以通过索引 (0, 1, 2, 3, 4, ...) 像数组那样访问每个项目。
- 访问 HTMLCollection 项目,可以通过它们的名称、id 或索引号。
- 访问 NodeList 项目,只能通过它们的索引号。
- 只有 NodeList 对象能包含属性节点和文本节点。
- 节点列表不是数组!
- 节点数组看起来像数组,但并不是。
- 您能够遍历节点列表并像数组那样引用其节点。
- 不过,您无法对节点列表使用数组方法,比如 valueOf()、push()、pop() 或 join()。