JavaScript DOM 基本操作:元素获取、遍历以及修改
<!-- HTML 文档结构 -->
<ul class="list">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
<li>item6</li>
</ul>
querySelectorAll(选择器):获取满足选择器( CSS 选择器 )条件的所有元素
let liList = document.querySelectorAll("li");
console.log(liList);
/** 返回元素节点列表(“类”数组)
* NodeList(6)
* 0: li
* 1: li
* 2: li
* 3: li
* 4: li
* 5: li
* length: 6
*/
获取的元素节点列表(NodeList)不是数组,但可以使用部分的数组方法:forEach()、entries()、item()、keys()、values() 等,也拥有 length 属性,也可以用 for of 遍历。
// for of 遍历
let liList = document.querySelectorAll("li");
console.log(liList);
for (let item of liList){
console.log(item);
}
// forEach() 遍历
liList.forEach(item => console.log(item));
// forEach() 遍历无返回值,如果需要返回值,需要将 NodeList 转换为数组,然后用 map() 操作
// 类数组 转换为 数组:Array.from() 或者 ...rest
let arrList = Array.from(liList); // 等同于:let arrList = [...liList];
console.log(arrList);
// 然后就可以用 map() 进行操作了
arrList.map(item => item.style.color = 'red') // 所有列表项的内容都显示为红色
querySelector(选择器):获取满足选择器条件的第一个元素
let firstList = document.querySelector("li");
console.log(firstList); /* <li>item1</li> */
// 也可以使用 querySelectorAll(选择器) 加索引获取第一个元素
let first = document.querySelectorAll("li")[0];
console.log(first.textContent); /* item1 */
过时的用法(不建议使用)
let firstList = document.getElementById('first');
let firstOne = document.getElementsByClassName('one')[0];
let firstOneByTag = document.getElementsByTagName('li')[0];
body
:document.body
,获取元素console.log(document.body);
// 等同于: console.log(document.querySelector('body'));
head
:document.head
,获取元素console.log(document.head);
// 等同于: console.log(document.querySelector('head'));
title
:document.title
,获取<title>
元素内部的文本console.log(document.title);
// 等同于: console.log(document.querySelector('title').textContent);
html
:document.documentElement
,获取元素console.log(document.documentElement);
// 等同于: console.log(document.querySelector('html'));
doctype
:document.doctype
,获取文档类型:<!DOCTYPE html>
console.log(document.doctype);
url
:document.URL
,获取当前页面的 url 地址console.log(document.URL);
window
:document.defaultView
,获取 window 对象console.log(document.defaultView);
cookie
:document.cookie
,获取 cookieconsole.log(document.cookie);
script
:document.scripts
,获取 script 脚本console.log(document.scripts);
styleSheets
:document.styleSheets
,获取样式console.log(document.styleSheets);
// HTML 文档结构
<form action="#" method="post" id="login">
<fieldset class="login" style="display: inline-grid; gap: 10px">
<legend>用户登录</legend>
<div>
<label for="email">邮箱:</label>
<input type="email" name="my_email" id="email" value="admin@php.cn" autofocus />
</div>
<div>
<label for="password">密码:</label>
<input type="password" name="password" id="password" value="123456" />
</div>
<button>提交</button>
</fieldset>
</form>
表单:
document.forms.id
,获取表单元素// 通用方法
console.log(document.querySelector('#login'));
// 快捷方法
console.log(document.forms); // 获取的是所有表单的集合
// 以下是获取指定的表单元素
console.log(document.forms[0]);
console.log(document.forms.item(0));
console.log(document.forms.login); // 推荐用法,简便、高效
控件:
forms.name/id
,获取表单控件元素// 从 document 为起点查找获取
// 通过控件 name 属性获取
console.log(document.forms.login.my_email); // 邮箱 <input> 元素
// 通过控件 id 属性获取
console.log(document.forms.login.email); // 邮箱 <input> 元素
// 也可以先获取 form 元素并赋值给变量,然后从获取的 form 元素为起点查找获取
let form = document.forms.login;
console.log(form.my_email);
console.log(form.my_email.value);
// 获取控件的值:forms.name/id.value
console.log(form.my_email.value); /* admin@php.cn */
console.log(form.password.value); /* 123456 */
拿到
form
中用户提交的邮箱和密码,然后进行封装和解析// 1,获取用户邮箱和密码
let email = document.forms.login.my_email.value;
let passWorld = document.forms.login.password.value;
// 2,封装成对象
let user = {email, passWorld}; // 属性名 和 属性值变量名 相同时可以只写 属性名。
// 2,对象(obj) 解析为 json 字符串
let json = JSON.stringify(user);
console.log(json); // {"email":"admin@php.cn","passWorld":"123456"}
知识点:节点类型(nodeType)
document:文档节点,9
element:元素节点,1
text:文本节点,3
<!-- HTML 文档结构 -->
<ul class="list">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
<li>item6</li>
</ul>
children
:获取所有元素类型子节点。(childNodes
:获取所有 {各种类型的} 子节点)// 获取 <ul> 元素
const list = document.querySelector('.list');
// childNodes 获取所有子节点(包含 文本节点 和 元素节点)
let nodeList = list.childNodes;
console.log(nodeList); /* NodeList(13) [text, li, text, li, text, li, text, li, text, li, text, li, text] */
// 只获取所有元素类型子节点,不要其他类型的节点
// 方法一:将 childNodes 获取的所有节点集合,转为数组,再用 filter() 筛选出元素节点
nodeList = [...nodeList].filter(item => item.nodeType == 1);
console.log(nodeList); /* [li, li, li, li, li, li] */ // 数组
// 方法二:children 直接获取所有元素类型子节点,推荐方法
elemList = list.children;
console.log(elemList); /* HTMLCollection(6) [li, li, li, li, li, li] */
firstElementChild
:获取第一个元素console.log(list.firstElementChild);
lastElementChild
:获取最后一个元素console.log(list.lastElementChild);
nextElementSibling
:获取下一个兄弟元素let first = list.firstElementChild; /* 第一个 li */
console.log(first.nextElementSibling); /* 第二个 li */
previousElementSibling
:获取前一个兄弟元素let last = list.lastElementChild; /* 最后一个 li */
console.log(last.previousElementSibling); /* 倒数第二个 li */
parentElement
:获取父元素let last = list.lastElementChild; /* 最后一个 li */
console.log(last.parentElement); /* li 的父元素 ul */
contains()
:是否是后代let last = list.lastElementChild; /* 子元素 li */
let parent = last.parentElement; /* 父元素 ul */
console.log(parent.contains(last)); /* true */
createElement()
: 创建新元素document.createElement('ul');
append()
: 添加新元素,在父元素上调用,默认添加到父元素的尾部(添加为最后的子元素)const ul = document.createElement('ul');
document.body.append(ul);
for (let i = 0; i < 6; i++){
const li = document.createElement('li');
li.append('item-' + (i +1));
ul.append(li);
}
/**
* 页面显示:
* · item-1
* · item-2
* · item-3
* · item-4
* · item-5
* · item-6
*/
// 注意,每次执行 append() 都会刷行一次页面,会造成页面闪烁和卡顿。
// 应该将要添加所有元素先添加到文档片段中,然后再 append() 将文档片段一次性添加到文档。
// 方法见下面的 createDocumentFragment()
createDocumentFragment()
: 创建文档片断const ul = document.createElement('ul');
document.body.append(ul);
const frag = document.createDocumentFragment();
for (let i = 0; i < 6; i++){
const li = document.createElement('li');
li.append('item-' + (i +1));
frag.append(li);
}
ul.append(frag);
before()
: 在前面追加,兄弟元素上调用const three = ul.querySelector(':nth-child(3)');
const li = document.createElement('li');
li.append('new item before three');
three.before(li);
/**
* · item-1
* · item-2
* · new item before three
* · item-3
* · item-4
* · item-5
* · item-6
*/
after()
: 在后面追加,兄弟元素上调用li = document.createElement('li');
li.append('new item after three');
three.after(li);
/**
* · item-1
* · item-2
* · new item before three
* · item-3
* · new item after three
* · item-4
* · item-5
* · item-6
*/
cloneNode()
: 克隆节点,带参数 true 表示包括子元素和文本,不带 true 则只复制元素本身(空元素)ul.append(li.cloneNode(true));
/**
* · item-1
* · item-2
* · new item before three
* · item-3
* · new item after three
* · item-4
* · item-5
* · item-6
* · new item after three
*/
replaceChild()
: 替换元素,两个参数,第一个是新的元素,第二个是要被替换的元素const p = document.createElement('p');
p.textContent = 'replaced';
ul.replaceChild(p, ul.lastElementChild);
/**
* · item-1
* · item-2
* · new item before three
* · item-3
* · new item after three
* · item-4
* · item-5
* · item-6
*
* replaced
*/
remove()
: 移除元素,在当前元素(要被删除的)上调用ul.lastElementChild.remove();
/**
* · item-1
* · item-2
* · new item before three
* · item-3
* · new item after three
* · item-4
* · item-5
* · item-6
*/
textContent
: 全部内容(包括 js,css,隐藏内容),推荐/**
* HTML 内容:
* <h3>php.cn<span style="display: none">hidden text</span></h3>
*/
// 获取
let textContent = document.querySelector('h3').textContent;
console.log(textContent); /* php.cnhidden text */
// 修改
document.querySelector('h3').textContent = '<p>new text</p>'
/**
* 页面显示:<p>new text</p>
* <p> 标签也被当做 <h3> 的文本内容
*/
innerText
: 返回已渲染(可见)内容/**
* HTML 内容:
* <h3>php.cn<span style="display: none">hidden text</span></h3>
*/
// 获取
textContent = document.querySelector('h3').innerText;
console.log(textContent); /* php.cn */
// 只能获取页面显示的内容
// 修改
document.querySelector('h3').innerText = '<p>new text</p>'
/**
* 页面显示:<p>new text</p>
* <p> 标签也被当做 <h3> 的文本内容
*/
innerHTML
: 替换元素内容(html)/**
* HTML 内容:
* <h3>php.cn<span style="display: none">hidden text</span></h3>
*/
// 获取
textContent = document.querySelector('h3').innerHTML;
console.log(textContent); /* php.cn<span style="display: none">hidden text</span> */
// 修改
document.querySelector('h3').innerHTML = '<p>new text</p>'
/**
* 页面显示:new text
* <p> 标签是 <h3> 的子元素
*/
outerHTML
: 替换元素自身(html)/**
* HTML 内容:
* <h3>php.cn<span style="display: none">hidden text</span></h3>
*/
// 获取
const outHtml = document.querySelector('h3').outerHTML;
console.log(outHtml); /* <h3>php.cn<span style="display: none">hidden text</span></h3> */
// 修改
document.querySelector('h3').outerHTML = '<p>Hello world!</p>';
/* 调用的元素 <h3> 自己被更改为 <p> */
document.querySelector('p').outerHTML = null;
/**
* 刚才生成的 <p> 被删除了
* 相当于 document.querySelector('p').remove();
*/
(1)插入位置
<!-- HTML 文档结构 -->
<ul class="list">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
<li>item6</li>
</ul>
beforebegin
:元素自身的前面,被调用元素起始标签(begin)的前面插入afterbegin
:插入元素内部的第一个子节点之前,被调用元素起始标签(begin)的后面插入beforeend
:插入元素内部的最后一个子节点之后,被调用元素结束标签(end)的前面插入afterend
:元素自身的后面,被调用元素结束标签(end)的后面插入
insertAdjacentElement()
:指定位置插入元素两个参数:第一个插入位置,第二个要插入的元素
注意:连续使用 insertAdjacentElement() 插入同一个元素,前面的插入语句会被后面的语句覆盖(即使插入的位置不同,或者元素的内容不同)!
const ul = document.querySelector('.list');
// 创建需要插入的元素
const h3beforebegin = document.createElement('h3');
h3beforebegin.textContent = 'beforebegin';
// 插入新创建的元素
ul.insertAdjacentElement('beforebegin', h3beforebegin); // 相当于 ul.before(h3beforebegin);
/**
* <h3>beforebegin</h3>
* <ul class="list">
* <li>item1</li>
* ......
* <li>item6</li>
* </ul>
*/
const h3afterebegin = document.createElement('h3');
h3afterebegin.textContent = 'afterebegin';
ul.insertAdjacentElement('afterbegin', h3afterebegin);
/**
* <h3>beforebegin</h3>
* <ul class="list">
* <h3>afterebegin</h3>
* <li>item1</li>
* ......
* <li>item6</li>
* </ul>
*/
const h3beforeend = document.createElement('h3');
h3beforeend.textContent = 'beforeend';
ul.insertAdjacentElement('beforeend', h3beforeend); // 相当于 ul.append(h3beforeend);
/**
* <h3>beforebegin</h3>
* <ul class="list">
* <h3>afterebegin</h3>
* <li>item1</li>
* ......
* <li>item6</li>
* <h3>beforeend</h3>
* </ul>
*/
const h3afterend = document.createElement('h3');
h3afterend.textContent = 'afterend';
ul.insertAdjacentElement('afterend', h3afterend); // 相当于 ul.after(h3afterend);
/**
* <h3>beforebegin</h3>
* <ul class="list">
* <h3>afterebegin</h3>
* <li>item1</li>
* ......
* <li>item6</li>
* <h3>beforeend</h3>
* </ul>
* <h3>afterend</h3>
*/
insertAdjacentText()
: 指定位置插入文本节点(不常用)const ul = document.querySelector('.list');
const textInsert = 'Hello world!';
ul.insertAdjacentText('beforebegin', textInsert);
/**
* Hello world!
* <ul class="list">
* <li>item1</li>
* ......
* <li>item6</li>
* </ul>
*/
insertAdjacentHTML()
: 指定位置插入元素节点(DOMString),重要// 可以将 HTML 代码片段,直接添加到页面中的指定的任何位置
// 而不用先封装成 Fragment,然后再 append() 添加
const ul = document.querySelector('.list');
ul.insertAdjacentHTML("afterend", '<button>删除</button>');
/**
* <ul class="list">......</ul>
* <button>删除</button>
*/