第十二篇 DOM 操作 - 常用方法 和 常用属性

by caix in 深圳

DOM 常用方法

获取节点

1、通过id号来获取元素,返回一个元素对象
document.getElementById("idName")
2、通过 name属性 获取元素,返回元素对象数组 NodeList
document.getElementsByName("name")
3、通过class来获取元素,返回元素对象数组 NodeList
document.getElementsByClassName("className")
4、通过标签名获取元素,返回元素对象数组 NodeList
document.getElementsByTagName("tagName")
5、DOM 中的每个 HTML 元素也是一个节点,可以像这样查找节点
通过 CSS 选择器(类名、Id、标签名)获取元素,H5 新增
如果通过 类名 或 Id 方式 获取,前面要加选择器符号 ‘.’ ‘#’
document.querySelector('h1')
document.querySelectorAll('h1')
querySeleor: 返回指定选择器的第一个元素对象,如有多个只取第一个
querySelorAll: 返回指定选择器的所有元素对象集合,NodeList

获取 / 设置 元素的属性值

let element = document.getElementById("idName")
1、括号传入属性名,返回对应属性的属性值
element.getAttribute("attributeName")
2、传入属性名及设置的值 给元素设置属性
element.setAttribute("attributeName","attributeValue")

创建节点 Node

let element = document.getElementById("idName")
1、创建一个 html 元素,这里以创建 h3 元素为例
document.createElement("h3")
2、创建一个文本节点
document.createTextNode("String")
3、创建一个属性节点,这里以创建 class 属性为例
element.createAttribute("class")

添加节点

let element = document.getElementById("idName")
1、往 element 内部最后面添加一个节点,参数是节点类型
element.appendChild(Node)
2、在 element 内部中的 existingNode 前面插入 newNode
element.insertBefore(newNode,existingNode)
3、往 element 内部最后面添加插入 Node节点 或 字符串
element.append(Node 或 "字符串" )
append 可插入Node节点或字符串,但 appendChild 只能插入 Node 节点
append 可传入多个参数但 appendChild 只接受一个参数
parent.append(Node, Node, 'Hello world')

删除节点

let element = document.getElementById("idName")
1、删除当前节点下指定的子节点,删除成功返回该被删除的节点,否则返回 null
element.removeChild(node)

DOM 常用属性

获取当前元素的父节点

let element = document.getElementById("idName")
返回当前元素的父节点对象
element.parentNode

获取当前元素的子节点

let element = document.getElementById("idName")
1、返回当前元素所有子元素节点对象,只返回 HTML 节点
element.children
2、返回当前元素所有子节点,包括文本,HTML,属性节点。(回车也会当做一个节点)
element.childNodes
3、返回当前元素的第一个子节点对象
element.firstChild
4、返回当前元素的最后一个子节点对象
element.lastChild

获取当前元素的同级元素

let element = document.getElementById("idName")
1、返回当前元素的下一个同级元素 没有就返回 null
element.nextSibling
2、返回当前元素上一个同级元素 没有就返回 null
element.previousSibling

获取当前元素的文本

let element = document.getElementById("idName")
1、返回元素的所有文本,包括 html 代码
element.innerHTML
2、返回当前元素的自身及子代所有文本值,只是文本内容,不包括 html 代码
element.innerText

获取当前节点的节点类型

let element = document.getElementById("idName")
1、返回节点的类型,数字形式(1-12
常见几个 1:元素节点,2:属性节点,3:文本节点
element.nodeType => 1

设置样式

let element = document.getElementById("idName")
1、设置元素的样式时使用 style
element.style.color = "#ffffff"

DOM 扩展

选择器

js 常用的功能就是根据 css 选择器与某个模式匹配的 DOM 元素

可以在类型 Docment、DocumentFragement、Element 中调用

querySelector() 方法

接收 CSS 选择符参数,返回匹配该模式的第一个后代元素,如果没有返回 null

在 Document 上使用时,会从文档元素开始搜索

在 Element 上使用时,则只会从当前元素的后代中查询

如果选择符有语法错误或碰到不支持的选择符,会抛异常

获取 <body> 元素
let body = document.querySelector("body")
获取 ID 为 “myDiv” 的元素
let myDiv = document.querySelector("#myDiv")
获取类名为 “selected” 的第一个元素
let selected = document.querySelector(".selected")
querySelectorAll() 方法

接收 CSS 选择符参数,返回所有匹配的节点,返回一个NodeList的静态实例(“快照”并非"实时"),如果没有 返回空的 NodeList 实例

可以在 Document、DocumentFragment 和 Element 类型上使用。如果选择符有语法错误或碰到不支持的选择符,会抛异常

取得 ID 为 "myDiv" 的 <div> 元素中的所有 <em> 元素
let ems = document.getElementById("myDiv").querySelectorAll("em");

返回的 NodeList 对象可以通过 for-of 循环、item()方法或中括号语法取得个别元素

let strongElements = document.querySelectorAll("p strong");
以下 3 个循环的效果一样
for (let strong of strongElements) {
strong.className = "important";
}
for (let i = 0; i < strongElements.length; ++i) {
strongElements.item(i).className = "important";
}
for (let i = 0; i < strongElements.length; ++i) {
strongElements[i].className = "important";
}
matchSelector() 方法

接收一个 CSS 选择符参数,如果元素匹配则该选择符返回 true,否则返回 false

if (document.body.matchSelector("body.page1")){
do something
}

元素遍历

E9 之前的版本不会把元素间的空格当成空白节点,而其他浏览器则会

这样就导致了 childNodes 和 firstChild 等属性上的差异

为了弥补这个差异,同时不影响 DOM 规范,W3C 通过新的 Element Traversal 规范定义了一组新属性

1、childElementCount 返回子元素数量(不包含文本节点和注释)

2、firstElementChild 指向第一个 Element 类型的子元素

3、lastElementChild 指向最后一个 Element 类型的子元素

4、previousElementSibling 指向前一个 Element 类型的同胞元素

5、nextElementSibling 指向后一个 Element 类型的同胞元素

原来要这样写
let parentElement = document.getElementById('parent');
let currentChildNode = parentElement.firstChild;
没有子元素,firstChild 返回 null,跳过循环
while (currentChildNode) {
if (currentChildNode.nodeType === 1) {
如果有元素节点,则做相应处理
processChild(currentChildNode);
}
if (currentChildNode === parentElement.lastChild) {
break;
}
currentChildNode = currentChildNode.nextSibling;
}
使用了 Element Traversal 简化后
let parentElement = document.getElementById('parent');
let currentChildElement = parentElement.firstElementChild;
没有子元素,firstElementChild 返回 null,跳过循环
while (currentChildElement) {
这就是元素节点,做相应处理
processChild(currentChildElement);
if (currentChildElement === parentElement.lastElementChild) {
break;
}
currentChildElement = currentChildElement.nextElementSibling;
}

CSS 类扩展

getElementsByClassName()

接收一个参数,即包含一个或多个类名的字符串,返回类名中包含相应类的元素的 NodeList

如果提供了多个类名,则顺序无关紧要

取得所有类名中包含 "username""current" 元素
这两个类名的顺序无关紧要
let allCurrentUsernames = document.getElementsByClassName("username current");
取得 ID"myDiv" 的元素子树中所有包含 "selected" 类的元素
let selected = document.getElementById("myDiv").getElementsByClassName("selected");
classList()

classList 是一个新的集合类型 DOMTokenList 的实例

与其他 DOM 集合类型一样,也有 length 属性表示自己包含多少项

也可以通过 item() 或 中括号 取得个别的元素

DOMTokenList 还增加了以下方法
1add(value) 向类名列表中添加指定的字符串值 value。如果这个值已经存在,则什么也不做
2contains(value) 返回布尔值,表示给定的 value 是否存在
调用 contains() 方法的应该是祖先节点,也就是搜索开始的节点,这个方法接收一个参数,即要检测的后代节点
3remove(value) 从类名列表中删除指定的字符串值 value
4toggle(value) 如果类名列表中已经存在指定的 value,则删除;如果不存在,则添加。
div.classList.remove("disabled"); => 删除"disabled"
div.classList.add("current"); => 添加"current"
for (let class of div.classList){ => 迭代类名
doStuff(class);
}

焦点管理

document.activeElement
document.activeElement 当前拥有焦点的DOM元素
默认情况下,页面加载后设置为 document.body, 页面加载之前为 null
document.hasFocus()
document.hasFocus() 文档是否拥有焦点,返回布尔值

HTMLDocument 扩展

readyState 属性
loading 文档正在加载
complete 文档加载完成
最好是把 document.readState 当成一个指示器,以判断文档是否加载完毕
代替以前依赖 onload 事件监听做处理逻辑
if (document.readyState == "complete"){
// 执行操作
}
compatMode 属性
指示当前浏览器处于什么渲染模式
"CSS1Compat" 标准模式
"BackCompat" 混杂模式
head 属性
let head = document.head => 直接取得 <head> 元素

自定义数据属性

给元素指定非标准属性,前缀是 data- , 通过 dataset 属性 访问 和 设置

<div id="myDiv" data-appId="12345" data-myname="Nicholas"></div>
let div = document.getElementById("myDiv");
取得自定义数据属性的值
let appId = div.dataset.appId;
let myName = div.dataset.myname;
设置自定义数据属性的值
div.dataset.appId = 23456;
div.dataset.myname = "Michael";
"myname" 吗?
if (div.dataset.myname){
console.log(`Hello, ${div.dataset.myname}`);
}

字符集属性

document.charset 属性 表示文档使用的字符集

docum.defaultCharset 属性 根据默认浏览器及操作系统的设置,当前文档默认的字符集

document.charset => 'UTF-8' // 获取
document.charset = 'UTF-8' // 设置

插入标签

innerHTML 属性
读模式 下返回调用元素的所有子节点
写模式 下根据指定的值创建新的 DOM 树,替换所有子元素
注意: 读模式得到子节点内容会被转义。 为 innerHTML 设置的包含 html 的字符串值与解析后 innnerHTML 的值大不相同。
div.innerHTML = '<p>dddd</p>';
outerHTML 属性
读模式 返回调用元素本身及它的所有子元素
写模式 替换调用元素
div.outerHTML
注意: 读模式得到内容会被转义
insertAdjacentHTML()

接收两个参数,插入的位置和要插入的 HTML 文本,第一个参数必须是下列值之一

"beforebegin" 在当前元素之前插入一个紧邻的同辈元素
"afterbegin" 在当前元素之下插入一个新的子元素或在第一个子元素之前再插入新的子元素
"beforeend" 在当前元素之下插入一个新的子元素或在最后一个子元素之后再插入新的子元素
"afterend" 在当前元素之后插入一个紧邻的同辈元素
元素前面、后面插入指定内容,作为同辈元素
element.insertAdjacentHTML('beforebegin', '<p>hello</p>')
element.insertAdjacentHTML('afterend', '<p>hello</p>')
元素内前面、后面插入指定内容,作为子元素
element.insertAdjacentHTML('afterbegin', '<p>hello</p>')
element.insertAdjacentHTML('beforeend', '<p>hello</p>')

内存与性能问题

被移除的元素之前有关联的事件处理或者其他js对象
之前的绑定关系会滞留在内存中
在使用 innerHTML、outerHTML 和 insertAdjacentHTML()之前
最好手动删除要 被替换的元素 上关联的 事件处理程序 和 JavaScript 对象

插入文本

innerText 属性
可以设置文本节点,也可以获取元素的文本信息
element.innerText = '<p>hello</p>';
对应 outerText 属性,这个属性会导致调用它的元素不存在,尽量不要用

滚动

scrollIntoView()
所有 HTML 元素都可以调用 scrollIntoView() 方法
通过滚动浏览器窗口或某个容器元素,调用元素就可以出现在视口中
当传入 true 或者不传入参,窗口滚动之后会让调用元素的顶部与视口顶部尽可能平齐。
当传入 false 调用元素会尽可能全部出现在视口中
调用元素的顶部与视口顶部尽可能平齐
div.scrollIntoView()
div.scrollIntoView(true)
调用元素会尽可能全部出现在视口中,不过顶部不一定对齐
可能调用元素的底部会与视口顶部平齐
div.scrollIntoView(false)
scrollIntoViewIfNeed()
scrollIntoViewIfNeed(true) => 参数可选,把不可见元素可见
scrollByLines()
scrollByLines(5) => 滚动到指定行
scrollByPages()
scrollByPages(-1) => 滚动指定页面高度,具体高度由元素的高度决定
posted @   caix-1987  阅读(222)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示