1.什么是节点
网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。
HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。
一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
1.DOM节点
1.DOM树里每一个内容都称之为节点
2.节点类型
1.元素节点 所有的标签 比如 body、 div (html 是根节点)
2.属性节点 所有的属性 比如 href
3.文本节点 所有的文本(文本节点包含文字、空格、换行等)
4.其他
2.查找节点
1.父节点查找
1.parentNode 属性
2.返回最近一级的父节点 找不到返回为null
3.语法
子元素.parentNode
<body>
<div>
<button>目标元素</button>
</div>
<script>
let button = document.querySelector('button');
// 先获取button 目标元素
console.dir(button);
console.dir(button.parentNode); // 获取到父元素 div标签
// 修改一下父元素的背景颜色
// console.dir(button.parentNode); // 获取到父元素 div标签
// button.parentNode.style.backgroundColor = 'red';
button.parentNode.style.display = 'none';
</script>
</body>
2.子节点查找
1.childNodes 获得所有子节点、包括文本节点(空格、换行)、注释节点等
2.children 仅获得所有元素节点 返回的还是一个伪数组
父元素.children
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>11-children.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
background-color: aqua;
padding: 20px;
}
li {
height: 30px;
background-color: yellow;
}
</style>
</head>
<body>
<ul>
<li>a1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<ul>
<li>b1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<ul>
<li>c1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
/*
1 获取到所有的ul标签 数组
2 遍历ul数组 挨个绑定点击事件
3 点击事件触发了
1 this = 当前被点击的ul标签
2 this.children 获取到 所有的ul的子元素 数组
3 遍历 children 获取到中的每一个li标签
4 li.style.display="none"
*/
// let ul=document.querySelector("ul");
// 获取ul标签下的 子节点
// console.log(ul.children);
// console.log(ul.childNodes);// 什么都那
// 1 获取到所有的ul标签 数组
let uls = document.querySelectorAll('ul');
// 遍历ul数组 挨个绑定点击事件
for (let index = 0; index < uls.length; index++) {
// 3 点击事件触发了
uls[index].addEventListener('click', function () {
// 3.1 3.2 3.3 对被点击的ul的children 做遍历
for (let j = 0; j < this.children.length; j++) {
// this.children[j] 表示 每一个li标签
this.children[j].style.display="none";
}
});
}
</script>
</body>
</html>
3.兄弟关系查找
1.nextElementSibling 属性 下一个兄弟节点
2.previousElementSibling 属性 上一个兄弟节点
<script>
/*
1 获取所有的li标签 数组
2 遍历 绑定点击事件
3 事件触发了
this.next
this.previou 获取到对应的元素 设置他们的样式
*/
// 1 获取所有的li标签 数组
let lis = document.querySelectorAll('li');
// 2 遍历 绑定点击事件
for (let index = 0; index < lis.length; index++) {
// 3 事件触发了
lis[index].addEventListener('click', function () {
// 上一个兄弟 设置 蓝色
this.previousElementSibling.style.backgroundColor = 'blue';
// 下一个兄弟 设置 绿色
this.nextElementSibling.style.backgroundColor = 'green';
});
}
</script>
3.增加节点
1.创建节点
1.即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点
2.创建元素节点方法:
//创造一个新的元素节点
document.createElement('标签名')
2.追加节点
1.appendChild
// 插入到父元素的最后一个子元素
父元素.appendChild(要插入的元素)
parent.appendChild(child) //将child的元素添加到parent元素里面去(最后面)
2.insertBofore
//插入到父元素中某个子元素的前面
父元素.insertBefore(要插入的元素,在那个元素前面)
parent.insertBofore(child, refChild)
//将child元素添加到refChild的前面去
//如果refChild元素获取不到, 会默认以appendChild形式添加
3.克隆节点
1.cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值
若为true,则代表克隆时会包含后代节点一起克隆
若为false,则代表克隆时不包含后代节点
默认为false
2.语法
//克隆一个已有的元素节点
元素.cloneNode(布尔值)
3.cloneNode() //浅克隆
4.cloneNode(true) //深克隆
<body>
<div class="box">div
<button>点击我</button>
</div>
<script>
//1.克隆节点 box这个盒子
let box = document.querySelector('.box')
//2.开始克隆
// let newBox1 = box.cloneNode() //浅克隆 不会把 div的后代节点一起克隆
let newBox2 = box.cloneNode(true) //ture 深克隆 会把div的后代节点一起克隆
//3 插入到body 标签中
// document.body.appendChild(newBox1)
document.body.appendChild(newBox2)
</script>
</body>
4.删除节点
1.若一个节点在页面中已不需要时,可以删除它
2.在 JavaScript 原生DOM操作中,要删除元素必须通过父元素删除
3.语法
父元素.removeChild(要删除的元素)
//如不存在父子关系则删除不成功
//删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从html中删除节点
父元素.remove()
//删除自己
<body>
<button>点我</button>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
<script>
let button = document.querySelector('button')
let ul = document.querySelector('ul')
//要删除的子元素
// let li =document.querySelector('li:last-child')
// let li =document.querySelector('li:first-child')
// let li = document.querySelector('li:nth-child(1)')
button.addEventListener('click', function () { //鼠标点击事件
let li =document.querySelector('li:last-child')
// 删除指定的元素
ul.removeChild(li);
// 删除自己
// ul.remove();
//button.remove()
});
</script>
5.时间对象
1.时间对象:用来表示时间的对象
2.作用:可以得到当前系统时间
1.实例化
1.在代码中发现了 new 关键字时,一般将这个操作称为实例化
2.创建一个时间对象并获取时间
3.获得当前时间
let data = new Date()
4.获得指定时间
let date = new Date ('1999-11-11')
2.时间对象方法
因为时间对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式
| 方法 | 作用 | 说明 |
|---|---|---|
| getFulllYear() | 获得年份 | 获取四位年份 |
| getMonth() | 获得月份 | 取值为0~11 |
| getDate() | 获得月份中的每一天 | 不同的月份取值也不相同 |
| getDay() | 获得星期 | 取值为0~6 |
| getHours() | 获得小时 | 取值为0~23 |
| getMinutes() | 获得分钟 | 取值为0~59 |
| getSeconds() | 获得秒 | 取值为0~59 |
3.获取当前时间案列
<script>
let div =document.querySelector('div')
setInterval (function () {
let date =new Date()
let year = date.getFullYear() //年
let month = date.getMonth() + 1 //月
let date1 = date.getDate() //号
let day = date.getDay() //星期几
let hours = date.getHours() //时
let minutes = date.getMinutes() //分
let seconds = date.getSeconds() //秒
div.style.fontSize='30px'
div.innerHTML=`${year}年${month}月${date1}号<br>星期${day}<br>${hours}时${minutes}分${seconds}秒`
},1000)
</script>
4.时间戳
1.什么是时间戳
是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式
2.三种方式获取时间戳
1.使用 getTime() 方法
//1. 实例化
let date = new Date()
// 2. 获取时间戳
console.log(dat.getTinme())
2. 简写 +new Date()
console.log(+(new Date()) );
//只要日期对象 可以使用 +将整个对象 转成 时间戳
3.使用 Date().now()
console.log(Date.now() );
6.重绘和回流
1.浏览器是如何进行界面渲染的
1.解析(Parser)HTML,生成DOM树(DOM Tree)
2.同时解析(Parser) CSS,生成样式规则 (Style Rules)
3.根据DOM树和样式规则,生成渲染树(Render Tree)
4.进行布局 Layout(回流/重排):根据生成的渲染树,得到节点的几何信息(位置,大小)
5.进行绘制 Painting(重绘): 根据计算和获取的信息进行整个页面的绘制
6.Display: 展示在页面上
2.重绘和回流(重排)
重绘不一定引起回流,而回流一定会引起重绘。
1.回流(重排)
当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过 程称为 回流。
2.重绘
由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、 outline等), 称为重绘。
3.会导致回流(重排)的操作:
1.页面的首次刷新
2.浏览器的窗口大小发生改变
3.元素的大小或位置发生改变
4.改变字体的大小
5.内容的变化(如:input框的输入,图片的大小)
6.激活css伪类 (如::hover)
7.脚本操作DOM(添加或者删除可见的DOM元素)
8.简单理解影响到布局了,就会有回流
7.综合案列
1.来回传菜
1.方法一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
width: 400px;
height: 400px;
}
li {
width: 400px;
height: 100px;
background-color: skyblue;
}
.left{
float: left;
background-color: pink;
}
.right{
float: right;
background-color: red;
}
</style>
</head>
<body>
<ul class="left">
<li>龙虾</li>
<li>鲍鱼</li>
<li>帝皇蟹</li>
<li>鱼子酱</li>
</ul>
<ul class="right">
</ul>
<script>
let left = document.querySelectorAll('li')
let right = document.querySelector('.right')
console.log(left);
console.log(right);
for (let index = 0; index < left.length; index++) {
left[index].addEventListener('click',function () {
console.log();
right.appendChild(left[index])
})
}
for (let index = 0; index < left.length; index++) {
left[index].addEventListener('click',function () {
console.log();
left.appendChild(left[index])
})
}
</script>
</body>
</html>
2.方法二
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>14-剪切-移动.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: space-between;
padding: 100px;
}
ul {
width: 300px;
}
.left {
background-color: yellow;
}
.right {
background-color: blueviolet;
}
</style>
</head>
<body>
<ul class="left">
<li>龙虾</li>
<li>鲍鱼</li>
<li>皇帝蟹</li>
<li>鱼子酱</li>
</ul>
<ul class="right"></ul>
<script>
/*
问题
1 移动的方向不确定
在判断 点击时候 先判断 哪个ul标签的子元素的长度为 0 就移动到谁哪里
*/
let lis = document.querySelectorAll('li');
let left = document.querySelector('.left');
let right = document.querySelector('.right');
// 准备要插入新元素的 父元素
let parent;
for (let index = 0; index < lis.length; index++) {
lis[index].addEventListener('click', function () {
// 先判断当前要插入到哪个标签中 谁的子元素长度为0 就插入到谁哪里
// right.appendChild(this);
if (right.children.length === 0) {
// 现在要插入到右边
parent = right;
}
if (left.children.length === 0) {
parent = left;
}
parent.appendChild(this);
});
}
</script>
</body>
</html>
3.方法三
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>14-剪切-移动.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: space-between;
padding: 100px;
}
ul {
width: 300px;
}
.left {
background-color: yellow;
}
.right {
background-color: blueviolet;
}
</style>
</head>
<body>
<ul class="left">
<li>龙虾</li>
<li>鲍鱼</li>
<li>皇帝蟹</li>
<li>鱼子酱</li>
</ul>
<ul class="right"></ul>
<script>
/*
要插入到哪里 不确定
1 获取被点击的元素的父元素
left > 皇帝蟹 this.parentNode
2 父元素之后 和 left 或者 right比较
如果 被点击的父元素 不等于 right ,设置 要插入的父元素 = right
如果 被点击的父元素 不等于 left ,设置 要插入的父元素 = left
*/
let lis = document.querySelectorAll('li');
let left = document.querySelector('.left');
let right = document.querySelector('.right');
let parent;
for (let index = 0; index < lis.length; index++) {
lis[index].addEventListener('click', function () {
// if (this.parentNode !== right) {
// parent = right;
// }
// if (this.parentNode !== left) {
// parent = left;
// }
parent = this.parentNode !== right ? right : left;
parent.appendChild(this);
});
}
</script>
</body>
</html>
2.页面渲染案列
素材
let data = [
{
src: 'images/course01.png',
title: 'Think PHP 5.0 博客系统实战项目演练111',
num: 1125
},
{
src: 'images/course02.png',
title: 'Android 网络动态图片加载实战',
num: 357
},
{
src: 'images/course03.png',
title: 'Angular2 大前端商城实战项目演练',
num: 22250
},
{
src: 'images/course04.png',
title: 'Android APP 实战项目演练',
num: 389
},
{
src: 'images/course05.png',
title: 'UGUI 源码深度分析案例',
num: 124
},
{
src: 'images/course06.png',
title: 'Kami2首页界面切换效果实战演练',
num: 432
},
{
src: 'images/course07.png',
title: 'UNITY 从入门到精通实战案例',
num: 888
},
{
src: 'images/course08.png',
title: 'Cocos 深度学习你不会错过的实战',
num: 590
},
{
src: 'images/course08.png',
title: '从入门到精通',
num: 5901
}
]
1.方法一
<!--
1 引入style.css
2 引入 data.js
3 根据data.js中的data数组 来遍历生成代码
最终让网页显示出来 data数组的数据
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./style.css">
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<script src="./data/data.js"></script>
<script>
// 头部
let html = `
<div class="box w">
<div class="box-hd">
<h3>精品推荐</h3>
<a href="#">查看全部</a>
</div>
<div class="box-bd">
<ul class="clearfix">
`
//中间部分
for (let index = 0; index < 10; index++) {
html+=`
<li>
<img src="images/course01.png" alt="" />
<h4>
Think PHP 5.0 博客系统实战项目演练
</h4>
<div class="info">
<span>高级</span> • <span>1125</span>人在学习
</div>
</li>
`
}
//尾部
html+= `
</ul>
</div>
</div>`
document.write(html)
</script>
</body>
</html>
2.方法二
<!--
1 引入style.css
2 引入 data.js
3 根据data.js中的data数组 来遍历生成代码
最终让网页显示出来 data数组的数据
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./style.css">
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<div class="box w">
<div class="box-hd">
<h3>精品推荐</h3>
<a href="#">查看全部</a>
</div>
<div class="box-bd">
<ul class="clearfix list"></ul>
</div>
</div>
<!-- 1 引入 要显示的数据 -->
<script src="./data/data.js"></script>
<!-- 2 在写自己的业务 -->
<script>
/*
1 获取到要渲染到页面中的数据 data
2 遍历data
要求使用 createElement appendChild 来往ul中插入 li 元素
1 创建一个li标签
2 创建一个图片便签 设置 src属性
3 创建一个h4标签 设置文本内容
4 创建一个div标签 添加一个class info
5 创建两个span标签
1个设置内容 高级
2个设置人数 1125
6 组装
li标签要 插入 img
li标签要 插入 h4
li标签要 插入 div.info
div.info 要插入两个span
ul插入 li
3 append可以插入多个元素 appendChild 只能插入一个元素
createTextNode 创建文件节点
*/
let ul =document.querySelector('.list') //获取ul标签
for (let index = 0; index < data.length; index++) { //遍历 data 数组
//创建li 标签
let li =document.createElement('li')
//创建img 图片标签
let img = document.createElement('img')
img.src = data[index].src
//创建h4标签
let h4 =document.createElement('h4')
h4.innerText = data[index].title
//创建div标签
let div =document.createElement('div')
div.classList.add('info') //div添加info 类名
let text1 = document.createTextNode(' • ');
let text2 = document.createTextNode('人在学习');
//创建span标签
let span1 =document.createElement('span')
span1.innerText = '高级' //span1的文字
let span2 =document.createElement('span')
span2.innerText = data[index].num //span2的文字
console.log(div[0]);
//将img h4 div 插入li标签对应的位置
div.append(span1, text1, span2, text2);
li.append(img, h4, div);
//将li标签 插入ul标签
ul.appendChild(li);
}
</script>
</body>
</html>