笔记目录
小概
本章分为大致两个知识点:DOM节点(节点与元素获取),DOM操作子节点的增删改查。 关键词:children,previousElementSibling,nextElementSibling,parentNode(获取父节点/元素),innerHTML,document.createElement(),appentChild,insterBefore,replaceChild,removeChild.
1. 网页内容(节点)
1.1 节点介绍
1.网页内容由四个部分组成 : 网页一切内容皆为 节点
* 标签节点(元素节点)
* 属性节点
* 文本节点
* 注释节点
2.节点作用 : 让渲染引擎可以更好的渲染页面
3.节点三要素
nodeType : 节点类型
noneName : 节点名词
nodeValue : 节点值
1.2 基础节点属性介绍
1.元素节点三要素
节点类型nodeType : 1
节点名称nodeName : 标签名大写
节点值 nodeValue : null
2.属性节点三要素
节点类型nodeType : 2
节点名称nodeName : 属性名
节点值 nodeValue : 属性值
3.文本节点三要素
节点类型nodeType : 3
节点名称nodeName : #text
节点值 nodeValue : 文本内容
4.注释节点三要素
节点类型nodeType : 8
节点名称nodeName : #comment
节点值 nodeValue : 注释内容
5.文档节点三要素
节点类型nodeType : 9
节点名称nodeName : #document
节点值 nodeValue : null
1.3 获取节点
- 获取子节点 子元素
<ul id="ul1">
我是文本
<!-- 我是注释 -->
<li>我是张三1</li>
<li id="li2">我是张三 2</li>
<li>我是张三3</li>
<li>我是张三4</li>
<li>我是张三5</li>
<p>66666</p>
</ul>
<scirpt>
let ul1 = document.querySelector('ul');
//1.获取子节点: 元素节点,文本节点,注释节点
console.log( ul1.childNodes );//
//2.获取子元素 :元素节点
console.log( ul1.children );
</scirpt>
- 获取兄弟节点与兄弟元素
<script>
/*学习目标: 获取兄弟节点与兄弟元素
1.获取上一个兄弟节点与元素 :
1.1 上一个节点: 元素.previousSibling
1.2 上一个元素: 元素.previousElementSibling
2.获取下一个兄弟节点与元素 :
1.1 下一个节点:元素.nextSibling
1.2 下一个元素:元素.nextElementSibling
*/
let ul1 = document.querySelector('#ul1');
let li2 = document.querySelector('#li2');
/* 上一个兄弟元素与节点 */
//1.1 上一个节点: 元素、文本、注释
console.log( li2.previousSibling );//空文本节点
//1.2 上一个元素: 一定是元素(标签)
console.log( li2.previousElementSibling);//li1
/* 下一个兄弟元素与节点 */
//1.1 下一个节点: 元素、文本、注释
console.log( li2.nextSibling );//空文本节点
//1.2 下一个元素: 一定是元素(标签)
console.log( li2.nextElementSibling);//li3
. 获取第一个(最后一个)子节点/子元素
获取第一个子节点和子元素/最后一个
获取第一个子节点:元素.first(last)child 获取第一个元素:元素.first(last)ElementChild
鸡肋:可以用.Child[0] .Child[父元素.child.length-1]
- 获取父节点 父元素
<script>
/*学习目标: 获取父节点
语法: 元素.parentNode
注意点: 父节点一定是获取元素,因为只有元素才可以有子节点
*/
let ul1 = document.querySelector('#ul1');
let li2 = document.querySelector('#li2');
//获取父节点: 得到的一定是元素标签
console.log( li2.parentNode );//ul1
console.log( li2.parentNode.parentNode );//body
console.log( li2.parentNode.parentNode.parentNode );//html
console.log( li2.parentNode.parentNode.parentNode.parentNode );//document(dom树)
console.log( li2.parentNode.parentNode.parentNode.parentNode.parentNode );//null
</script>
找到头了的就返回null
2. DOM增删改查
2.1 创建元素的三种方式
- document.write()
- innerHTML
- (常用) document.createElement()
(1)创建一个空元素 : 只是内存创建,并没有挂载到DOM树
(2)设置样式
(3)添加到dom树 : 此时渲染引擎才会渲染到DOM树
let box = document.querySelector('.box');
//1.document.write() : 几乎不用,因为可能覆盖原来内容
/*
特点: ‘可能’会覆盖网页原本的内容
原理: 当渲染引擎开始从上往下渲染DOM树的时候,此时会生成一个文档流(标准流)。一旦页面完成渲染,此时默认文档流就会关闭。如果你调用了document.write(),则页面会重新生成一个文档流。此时就会覆盖之前的内容。
不会覆盖 : 在默认文档流没有关闭之前调用
会覆盖 : 默认文档流关闭之后调用 (事件)
*/
document.write('<h1>我是标题</h1>');
//2.innerHTML : 少用,存在性能问题
//替换内容 = : 赋值,会先把旧值回收,然后存入新值
// document.body.innerHTML = '<a href="#">我是链接</a>';
//新增内容 += : 自己原来的基础上进行拼接字符串
// document.body.innerHTML += '<a href="#">我是链接</a>';
//3.DOM推荐使用 : document.createElement()
//(1)在内存中创建一个空元素
let a = document.createElement('a');
//(2)设置样式
a.href = '#';
a.innerText = '黑马程序员';
a.style.color = 'cyan';
//(3)添加(挂载)到DOM树 : 渲染引擎才会渲染
box.appendChild(a);
补充:insertAdjacentHTML(‘插入的位置’,‘插入的文本’),测试了一下,没发现innerHTML的性能问题。
2.2 添加子元素
添加子元素: 父元素.appendChild(子元素)
1.元素是 新创建的 : 则是’添加’到 最后面
2.元素 已存在 : 则是 ‘移动’ 到最后面
3.元素 有子元素 : 则元素和子元素一起 移动 到最后面
<ul id="ul1">
<li>我是张三1</li>
<li id="li2">我是张三2</li>
<li>我是张三3</li>
<li>我是张三4</li>
<li>我是张三5</li>
</ul>
<ul id="ul2">
<li>我是李四1</li>
<li>我是李四2</li>
<li id="li3">我是李四3</li>
<li>我是李四4</li>
<li>我是李四5</li>
</ul>
js//
let ul1 = document.querySelector('#ul1');
let li2 = document.querySelector('#li2');
let ul2 = document.querySelector('#ul2');
let li3 = document.querySelector('#li3');
//1.元素是 新创建的 : 则是添加到最后面
let newLi = document.createElement('li');
newLi.innerText = '我是新来的';
ul1.appendChild(newLi);
//2.元素 已存在 : 则是移动到最后面
ul1.appendChild(li3);
//3.元素 有子元素 : 则元素和子元素一起 移动到最后面
ul1.appendChild(ul2);
2.3 插入子元素
2.插入子元素 父元素.insertBefore(A新元素,B旧元素) A元素插入到B元素的前面
1.1.元素是 新创建的 : 则是’添加’到 指定位置
1.2.元素 已存在 : 则是 ‘移动’ 到 指定位置
1.3.元素 有子元素 : 则元素和子元素一起 移动 到指定位置
let ul1 = document.querySelector('#ul1');
let li2 = document.querySelector('#li2');
let ul2 = document.querySelector('#ul2');
let li3 = document.querySelector('#li3');
//1.元素是 新创建的 : 则是添加到指定位置
let newLi = document.createElement('li');
newLi.innerText = '我是新来的';
ul1.insertBefore(newLi,li2);;//newLi插入到li2的前面
//2.元素 已存在 : 则是移动到 指定位置
ul1.insertBefore(li3,li2);//li3插入到li2的前面
//3.元素 有子元素 : 则元素和子元素一起 移动到指定位置
ul1.insertBefore(ul2,li2);//ul2插入到li2的前面
2.4 替换子元素
替换子元素: 父元素.replaceChild(A元素,B元素) A替换B
1.元素是 新创建的 : 则是替换元素
2.元素 已存在 : 则是先移动,后替换
3.元素 有子元素 : 则元素和子元素一起 先移动,后替换
let ul1 = document.querySelector('#ul1');
let li2 = document.querySelector('#li2');
let ul2 = document.querySelector('#ul2');
let li3 = document.querySelector('#li3');
//1.元素是 新创建的 : 则是替换元素
let newLi = document.createElement('li');
newLi.innerText = '我是新来的';
// ul1.replaceChild(newLi,li2);//newLi替换li2
//2.元素 已存在 : 则是 先移动,后替换
// ul1.replaceChild(li3,li2);//li3替换li2
//3.元素 有子元素 : 则元素和子元素一起 移动到最后面
ul1.replaceChild(ul2,li2);//ul2替换li2
2.5 删除子元素
删除子元素: 父元素.removeChild(子元素)
*** 1.父元素只能移除自己的子元素
2.父元素不能移除别人的子元素
3.元素不能移出自身
let ul1 = document.querySelector('#ul1');
let li2 = document.querySelector('#li2');
let ul2 = document.querySelector('#ul2');
let li3 = document.querySelector('#li3');
//(1)元素不能自己移出自己的
// li2.removeChild(li2);
//(2)父元素不能移出别人的子元素
// ul1.removeChild(li3);
//(3)父元素只能移除自己的子元素
// ul1.removeChild(li2);
/* 细节: 子元素间接移除父元素 */
// li2.parentNode.parentNode.removeChild(ul1);
3. 穿梭框案例
<body>
<select name="" id="left" multiple>
<option value="">web工程师</option>
<option value="">android工程师</option>
<option value="">ios工程师</option>
<option value="">php工程师</option>
<option value="">nodejs工程师</option>
<option value="">pyton小白</option>
<option value="">足疗爱好者</option>
</select>
<button id="btn1">>></button>
<button id="btn2"><<</button>
<button id="btn3">></button>
<button id="btn4"><</button>
<select name="" id="right" multiple></select>
<script>
/* 需求分析
点击btn1 : 全部右移, 遍历left每一个子元素,添加到right
点击btn2 : 全部左移, 遍历right每一个子元素,添加到left
点击btn3 : 选中右移, 遍历left每一个子元素,将选中的option 添加到right
点击btn4 : 选中左移, 遍历right每一个子元素,将选中的option 添加到left
*/
//1.获取元素
let left = document.querySelector('#left');
let right = document.querySelector('#right');
let btn1 = document.querySelector('#btn1');
let btn2 = document.querySelector('#btn2');
let btn3 = document.querySelector('#btn3');
let btn4 = document.querySelector('#btn4');
//2.注册事件
//1.点击btn1 : 全部右移
btn1.onclick = function(){
//3.事件处理: 遍历left每一个子元素,添加到right
for(let i =0;i<left.children.length;i++){
// console.log(left.children[i]);
/*
(1)问题 : 元素无法全部移动
(2)分析 : 当移动数组的元素的时候,数组后面的元素就会前移(导致长度和下标变化)
(3)解决 : 循环变量不自增
*/
right.appendChild( left.children[i] );
i--;//抵消本次循环变量自增
};
};
//2.点击btn2 : 全部左移
btn2.onclick = function(){
//3.事件处理: 遍历right每一个子元素,添加到left
for(let i =0;i<right.children.length;i++){
left.appendChild( right.children[i] );
i--;//抵消本次循环变量自增
};
};
//3.点击btn3 : 选中右移
btn3.onclick = function(){
for(let i =0;i<left.children.length;i++){
//判断是否选中
if( left.children[i].selected ){
right.appendChild( left.children[i] );
i--;//抵消本次循环变量自增
};
};
};
//4.点击btn4 : 选中左移
btn4.onclick = function(){
for(let i =0;i<right.children.length;i++){
if( right.children[i].selected ){
left.appendChild( right.children[i] );
i--;//抵消本次循环变量自增
};
};
};
</script>
总结
需要记得单词稍微多些,多是组合单词,至少要保证看到这个单词立刻明白这个方法怎么使用。