JS HTML DOM
当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。
通过 HTML DOM,JavaScript 能够访问和改变 HTML 文档的所有元素。
DOM文档操作
查找 HTML 元素
方法 | 描述 | 例子 |
---|---|---|
document.getElementById(id) | 通过元素 id 来查找元素 | 查找 id=“intro” 的元素:let myElement = document.getElementById(“intro”); |
document.getElementsByTagName(name) | 通过标签名来查找元素 | 查找所有 <p> 元素: myElement = document.getElementsByTagName(“p”); |
document.getElementsByClassName(name) | 通过类名来查找元素 | 查找包含 class=“intro” 的所有元素的列表:document.getElementsByClassName(“intro”); |
document.querySelectorAll(“tag.css_name”) | CSS 选择器查找 HTML 元素 | 返回 class=“intro” 的所有 <p> 元素列表: let el=document.querySelectorAll(“p.intro”); |
例如:查到id为demo的元素下面<p>标签元素
<!DOCTYPE html>
<html>
<body>
<h1>
demo页面
</h1>
<div id="demo">
<p> this is demo p tag</p>
<p> hello demo</p>
</div>
<p id="message">message</p>
<script>
let div_tags = document.getElementById("demo")
let p_tags = div_tags.getElementsByTagName("p")
document.getElementById("message").innerHTML = "message is " + p_tags[0].innerHTML
</script>
</body>
</html>
改变 HTML 元素
方法 | 描述 | 例子 |
---|---|---|
element.innerHTML = new html content | 改变元素的 inner HTML | 修改<p>元素的内容:document.getElementById(“p_msg”)=“Hello world!!”; |
element.attribute = new value | 改变 HTML 元素的属性值 | 修改<img>元素的src属性:document.getElementById(“image”).src = “/i/porsche.jpg”; |
element.setAttribute(attribute, value) | 改变 HTML 元素的属性值 | 给id为message的元素添加name属性:document.getElementById(“message”).setAttribute(“name”, “change_attr”) |
element.style.property = new style | 改变 HTML 元素的样式 | 改变<p>元素的样式:document.getElementById(“message”).style.color=“blue”; |
添加和删除元素
方法 | 描述 |
---|---|
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} | 向 onclick 事件添加事件处理程序 |
查找 HTML 对象
HTML有很多的属性,此时仅仅列举常用几个属性
属性 | 说明 |
---|---|
document.forms | 返回所有的<form>元素 |
document.images | 返回所有的<img>元素 |
document.links | 返回拥有 href 属性的所有\ 和 <a> 元素 |
例如:查找 id=“frm1” 的 form 元素,在 forms 集合中,然后显示所有元素值
<!DOCTYPE html>
<html>
<body>
<h1>使用 document.forms 查找 HTML 元素</h1>
<form id="frm1" action="/demo/action_page.php">
First name: <input type="text" name="fname" value="Bill"><br>
Last name: <input type="text" name="lname" value="Gates"><br><br>
<input type="submit" value="提交">
</form>
<p>单击“试一试”按钮,显示表单中每个元素的值。</p>
<button onclick="myFunction()">试一试</button>
<p id="demo"></p>
<script>
function myFunction() {
let x = document.forms["frm1"];
let text = "";
let i;
for (i = 0; i < x.length ;i++) {
text += x.elements[i].value + "<br>";
}
document.getElementById("demo").innerHTML = text;
}
</script>
</body>
</html>
元素element常用属性
属性/方法 | 说明 |
---|---|
element.innerHTML | 设置或返回元素的内容。 |
element.id | 设置或返回元素的 id。 |
element.className | 设置或返回元素的 class 属性。 |
element.tagName | 返回元素的标签名。 |
element.style | 设置或返回元素的 style 属性。 |
element.textContent | 设置或返回节点及其后代的文本内容。 |
element.title | 设置或返回元素的 title 属性。 |
element.attributes | 返回元素属性的 NamedNodeMap。NamedNodeMap 对象表示元素属性节点的无序集合。NamedNodeMap 中的节点可通过名称或索引(数字)来访问。 |
element.getAttribute() | 返回元素节点的指定属性值。 |
element.getAttributeNode() | 返回指定的属性节点。 |
element.getElementsByTagName() | 返回拥有指定标签名的所有子元素的集合。 |
element.hasAttribute() | 如果元素拥有指定属性,则返回true,否则返回 false。 |
element.hasAttributes() | 如果元素拥有属性,则返回 true,否则返回 false。 |
element.setAttribute() | 把指定属性设置或更改为指定值。 |
element.toString() | 把元素转换为字符串。 |
更多属性,请参考:element 对象属性
属性attr对象
在 HTML DOM 中,attr 对象表示 HTML 属性。
NamedNodeMap 对象表示元素属性节点的无序集合。
NamedNodeMap 中的节点可通过名称或索引(数字)来访问。
常用attribute的属性和操作方法:
属性/方法 | 说明 |
---|---|
attr.isId | 如果属性是 id 类型,则返回 true,否则返回 false。 |
attr.name | 返回属性的名称。 |
attr.value | 设置或返回属性的值。 |
attr.specified | 如果已指定属性,则返回 true,否则返回 false。 |
nodemap.getNamedItem() | 从 NamedNodeMap 返回指定的属性节点。 |
nodemap.item() | 返回 NamedNodeMap 中位于指定下标的节点。 |
nodemap.length | 返回 NamedNodeMap 中的节点数。 |
nodemap.removeNamedItem() | 移除指定的属性节点。 |
nodemap.setNamedItem() | 设置指定的属性节点(通过名称)。 |
示例:
<!DOCTYPE html>
<html>
<body>
<h1>
demo页面
</h1>
<div id="demo">
<p> this is demo p tag</p>
<p> hello demo</p>
</div>
<p id="message">message</p>
<script>
let div_tags = document.getElementById("demo")
let p_tags = div_tags.getElementsByTagName("p")
document.getElementById("message").setAttribute("name", "change_attr")
// 返回属性的名称和值
console.log(document.getElementById("message").attributes[1].name,
document.getElementById("message").attributes[1].value)
// 返回指定属性的值
let el = document.getElementById("message")
let el_map = el.attributes
// getNamedItem() 方法从 namedNodeMap 中返回具有指定名称的属性节点
console.log(el_map.getNamedItem("name").value)
console.log(el_map.getNamedItem("name").textContent)
// setNamedItem() 方法向 nodeMap 添加指定的节点。
let new_attr = document.createAttribute("class")
new_attr.value = "test_data"
el_map.setNamedItem(new_attr)
console.log(el_map.getNamedItem("class").value)
</script>
</body>
</html>
DOM事件
DOM可以使用JavaScript对HTML事件作出反应。
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!
我们可以在HTML动定义event handler,满足条件时触发对应的JavaScript。
常用事件句柄如下:
事件句柄 | 说明 |
---|---|
onclick | 当用户点击某个对象时调用的事件句柄。 |
ondblclick | 当用户双击某个对象时调用的事件句柄。 |
onfocus | 元素获得焦点。 |
onchange | 当用户改变输入字段内容。经常与输入字段验证结合使用。 |
onload | 用户登陆页面,或者一张页面或一幅图像完成加载。 |
onunload | 用户退出页面。可用于处理 cookie。 |
onmouseover | 鼠标移到某元素之上。 |
onmousemove | 鼠标被移动。 |
onreset | 重置按钮被点击。 |
onselect | 文本被选中。 |
onsubmit | 确认按钮被点击。 |
onerror | 在加载文档或图像时发生错误。 |
示例:
<!DOCTYPE html>
<html>
<body>
<h1>
demo页面
</h1>
配置1: <input type="text" id="f_1" value="配置1">
<br>
配置2: <input type="text" id="f_2">
<br>
<p>点击button复制配置</p>
</br>
<br>
<button onclick="func_copy()">复制</button>
</br>
<script>
function func_copy() {
let data = document.getElementById("f_1").value
document.getElementById("f_2").value = data
}
</script>
</body>
</html>
更多事件,请参考:事件类型
DOM 事件监听器
addEventListener() 方法
为元素附加事件处理程序而不会覆盖已有的事件处理程序;一个事件可以添加多个监听器。
用法:
element.addEventListener(event, function, useCapture);
第一个参数是事件的类型(比如 "click" 或 "mousedown")。
第二个参数是当事件发生时我们需要调用的函数。
第三个参数是布尔值,指定使用事件冒泡还是事件捕获。此参数是可选的。
注意:请勿对事件使用 "on" 前缀;请使用 "click" 代替 "onclick"。
示例:
<!DOCTYPE html>
<html>
<body>
<h1>
demo页面
</h1>
配置1: <input type="text" id="f_1" value="配置1">
<br>
配置2: <input type="text" id="f_2">
<br>
<p>点击button复制配置</p>
</br>
<br>
<button id="btn_1">复制</button>
</br>
<script>
bt_el = document.getElementById("btn_1")
bt_el.addEventListener("click", func_copy)
function func_copy() {
let data = document.getElementById("f_1").value
document.getElementById("f_2").value = data
}
</script>
</body>
</html>
传递参数
当传递参数值时,需要以参数形式使用调用指定函数的“匿名函数”
element.addEventListener("click", function(){ myFunction(p1, p2); });
示例:
<!DOCTYPE html>
<html>
<body>
<h1>
demo页面
</h1>
数据: <input type="text" id="input_1">
<br>
数据: <input type="text" id="input_2">
<br>
<button id="btn_1">计算</button>
</br>
<br>
结果: <input type="text" id="output">
<br>
<script>
x = 1
y = 3
let bt_el = document.getElementById("btn_1");
bt_el.addEventListener("click", function() {
func_add(x, y);
});
function func_add(x, y) {
let d1_el = document.getElementById("input_1")
let d1 = d1_el.value
let d2_el = document.getElementById("input_2")
let d2 = d2_el.value
res = d1 * x + d2 * y
out_el = document.getElementById("output");
out_el.setAttribute("value", res);
};
</script>
</body>
</html>
冒泡和捕获
在 HTML DOM 中有两种事件传播的方法:冒泡和捕获。
事件传播是一种定义当发生事件时元素次序的方法。假如 <div> 元素内有一个 <p>,然后用户点击了这个 <p> 元素,应该首先处理哪个元素“click”事件?
- 在冒泡中,最内侧元素的事件会首先被处理,然后是更外侧的:首先处理 <p> 元素的点击事件,然后是 <div> 元素的点击事件。
- 在捕获中,最外侧元素的事件会首先被处理,然后是更内侧的:首先处理 <div> 元素的点击事件,然后是 <p> 元素的点击事件。
在 addEventListener() 方法中,通过使用“useCapture”参数来规定传播类型:
addEventListener(event, function, useCapture);
默认值是 false,将使用冒泡传播,如果该值设置为 true,则事件使用捕获传播。
removeEventListener() 方法
removeEventListener() 方法会删除已通过 addEventListener() 方法附加的事件处理程序
element.removeEventListener("mousemove", myFunction);
DOM节点
通过 HTML DOM,可以使用节点关系来导航节点树。
节点类型
HTML 文档中的所有事物都是节点:
- 整个文档是文档节点
- 每个 HTML 元素是元素节点
- HTML 元素内的文本是文本节点
- 每个 HTML 属性是属性节点
- 所有注释是注释节点
节点关系
节点树中的节点彼此之间有一定的等级关系,术语(父、子和同胞,parent、child 以及 sibling)用于描述这些关系。
- 在节点树中,顶端节点被称为根(根节点)。
- 每个节点都有父节点,除了根(根节点没有父节点)。
- 节点能够拥有一定数量的子
- 同胞(兄弟或姐妹)指的是拥有相同父的节点。
通过 JavaScript,您可以使用以下节点属性在节点之间导航:
- parentNode
- childNodes[nodenumber]
- firstChild
- lastChild
- nextSibling
- previousSibling
子节点和节点值
文本节点
文本节点的值能够通过节点的 innerHTML 属性进行访问,
访问 innerHTML 属性等同于访问首个子节点的 nodeValue。
示例:
<!DOCTYPE html>
<html>
<body>
<h1>
demo页面
</h1>
<p id="ps_1">hello world</p>
<script>
// 文本节点的值能够通过节点的 innerHTML 属性进行访问
data = document.getElementById("ps_1").innerHTML
// 访问 innerHTML 属性等同于访问首个子节点的 nodeValue
data_2 = document.getElementById("ps_1").childNodes[0].nodeValue
data_3 = document.getElementById("ps_1").firstChild.nodeValue
console.log(data)
console.log(data_2)
console.log(data_3)
</script>
</body>
</html>
nodeName 属性
nodeName 属性规定节点的名称。
- nodeName 是只读的
- 元素节点的 nodeName 等同于标签名
- 属性节点的 nodeName 是属性名称
- 文本节点nodeName 总是 #text
- 文档节点的 nodeName 总是 #document
nodeValue 属性
nodeValue 属性规定节点的值。
- 元素节点的 nodeValue 是 undefined
- 文本节点的 nodeValue 是文本
- 属性节点的 nodeValue 是属性值
DOM节点操作
创建新 HTML 元素(节点)
如需向 HTML DOM 添加新元素,必须首先创建这个元素(元素节点),然后将其追加到已有元素。
appendChild() 方法,追加新元素作为父的最后一个子
示例:
<!DOCTYPE html>
<html>
<body>
<h1>
demo页面
</h1>
<div>
<p id="ps_1">段落文本2</p>
<p id="ps_1">段落文本1</p>
</div>
<script>
let new_el = document.createElement("p") //创建元素
let node = document.createTextNode("文本段落new") //添加文本节点
new_el.appendChild(node)
let div_el = document.getElementsByTagName("div")[0]
div_el.appendChild(new_el)
</script>
</body>
</html>
insertBefore(new_el, el) 方法将新元素插入到指定元素的前面
<!DOCTYPE html>
<html>
<body>
<h1>
demo页面
</h1>
<div>
<p id="ps_1">段落文本1</p>
<p id="ps_2">段落文本2</p>
</div>
<script>
let new_el = document.createElement("p") //创建元素
let node = document.createTextNode("文本段落new") //添加文本节点
new_el.appendChild(node)
let div_el = document.getElementsByTagName("div")[0]
div_el.insertBefore(new_el, document.getElementById("ps_2"))
</script>
</body>
</html>
删除已有 HTML 元素
如需删除某个 HTML 元素,需要先找到该元素的父
<!DOCTYPE html>
<html>
<body>
<h1>
demo页面
</h1>
<div>
<p id="ps_1">段落文本1</p>
<p id="ps_2">段落文本2</p>
</div>
<script>
//被删除子元素
let child_el = document.getElementById("ps_2");
//被删除子元素的父元素
let parent_el = child_el.parentElement;
parent_el.removeChild(child_el)
</script>
</body>
</html>
替换 HTML 元素
replaceChild() 方法用来替换元素,也需要找到响应的父元素
parent_el.replaceChild(new_child, old_child_el)
示例:
<!DOCTYPE html>
<html>
<body>
<h1>
demo页面
</h1>
<div>
<p id="ps_1">段落文本1</p>
<p id="ps_2">段落文本2</p>
</div>
<script>
//新元素
let new_child = document.createElement("p")
let new_node = document.createTextNode("新段落")
new_child.appendChild(new_node)
//子元素
let old_child_el = document.getElementById("ps_2");
//子元素的父元素
let parent_el = child_el.parentElement;
parent_el.replaceChild(new_child, old_child_el)
</script>
</body>
</html>
表单操作
表单的输入框、下拉框等可以接收用户输入,所以用JavaScript来操作表单,可以获得用户输入的内容,或者对一个输入框设置新的内容。
HTML表单的输入控件主要有以下几种:
- 文本框,对应的<input type=“text”>,用于输入文本;
- 口令框,对应的<input type=“password”>,用于输入口令;
- 单选框,对应的<input type=“radio”>,用于选择一项;
- 复选框,对应的<input type=“checkbox”>,用于选择多项;
- 下拉框,对应的<select>,用于选择一项;
- 隐藏文本,对应的<input type=“hidden”>,用户不可见,但表单提交时会把隐藏文本发送到服务器。
获取值
- 使用element.value获取可以获取类型为text、password、hidden以及select的值。
- 对于单选框和复选框,value属性返回的永远是HTML预设的值,而我们需要获得的实际是用户是否“勾上了”选项,所以应该用checked判断
<div>
<input type="text" id="email_add">
<input type="button" id="bt" onclick="submit_func()" value="submit">
</div>
<script>
function submit_func()
{
let input = document.getElementById("email_add")
input.value = "input: " + input.value //修改text控件的文本
console.log(input.value)
}
</script>
设置值
- 设置值和获取值类似,对于text、password、hidden以及select,直接设置value就可以
- 对于单选框和复选框,设置checked为true或false即可
提交表单
JavaScript可以以两种方式来处理表单的提交
- 方式一:通过<form>元素的submit()方法提交一个表单,
例如,响应一个<button>的click事件
<div>
<form id = "form_1">
<input type="text" id="email_add">
<input type="button" id="bt" onclick="submit_func()" value="submit">
</form>
</div>
<script>
function submit_func()
{
let form = document.getElementById("form_1")
let input = document.getElementById("email_add")
input.value = "input: " + input.value //修改text控件的文本
console.log(input.value)
form.submit()
}
</script>
- 方式二:响应本身的onsubmit事件,在提交form时作修改。
JS Browser BOM
浏览器对象模型Browser Object Model (BOM)
Window 对象
主要用来新建/关闭/调整窗口
所有浏览器都支持 window 对象。它代表浏览器的窗口。
所有全局 JavaScript 对象,函数和变量自动成为 window 对象的成员。
全局变量是 window 对象的属性。
全局函数是 window 对象的方法。
window.document.getElementById("header");
等同于:
document.getElementById("header");
窗口相关方法
方法 | 说明 |
---|---|
window.innerHeight | 浏览器窗口的内高度(以像素计) |
window.innerWidth | 浏览器窗口的内宽度(以像素计) |
window.open() | 打开新窗口 |
window.close() | 关闭当前窗口 |
window.moveTo() | 移动当前窗口 |
window.resizeTo() | 重新调整当前窗口 |
Screen 对象
window.screen 对象包含用户屏幕的信息, window.screen 对象不带 window 前缀也可以写为screen。
常用属性:
属性 | 说明 |
---|---|
screen.width | 以像素计的访问者屏幕宽度 |
screen.height | 以像素计的访问者屏幕的高度 |
screen.availWidth | 可用宽度。访问者屏幕的宽度,以像素计,减去诸如窗口工具条之类的界面特征。 |
screen.availHeight | 可用高度。访问者屏幕的高度,以像素计,减去诸如窗口工具条之类的界面特征。 |
screen.colorDepth | 返回用于显示一种颜色的比特数。 |
screen.pixelDepth | 返回屏幕的像素深度。颜色深度和像素深度是相等的。 |
location 对象
window.location 对象可用于获取当前页面地址(URL)并把浏览器重定向到新页面。
window.location 对象可不带 window 前缀书写。
常用属性:
属性 | 说明 |
---|---|
window.location.href | 返回当前页面的 href (URL) |
window.location.hostname | 返回 web 主机的域名 |
window.location.pathname | 返回当前页面的路径或文件名 |
window.location.protocol | 返回使用的 web 协议(http: 或 https:) |
window.location.assign | 加载新文档 |
history对象
window.history 对象包含浏览器历史。
常用属性:
属性 | 说明 |
---|---|
history.back() | 等同于在浏览器点击后退按钮 |
history.forward() | 等同于在浏览器中点击前进按钮 |
参考文献:
https://www.w3school.com.cn/js/js_htmldom_document.asp
https://www.w3school.com.cn/jsref/dom_obj_all.asp