DOM与BOM
BOM:一整套操作浏览器相关内容的属性和方法(浏览器对象模型)
DOM:一整套操作文档流相关内容的属性和方法(文档对象模型)
首先需要获取元素,然后再操作元素(文本内容、超文本内容)
对于dom的操作:
dom的on click
DOM由节点组成,元素/标签是节点中的一种,节点一共分为12种。
其中每一个元素都是一个节点,节点不一定是元素,元素仅仅是节点的一种。
通过nodeType属性判断节点的类型,需要记住4种。
1.元素类型 3.文本类型 8.注释 9.文档
案例:回到顶部
需求:
滚动条滚动超过零界点,顶部通栏显示,否则隐藏。
滚动条超过零界点,回到顶部按钮显示,否则隐藏。
点击回到顶部按钮,滚动条滚动回到顶部。
布局结构:
顶部通栏的标签,回到顶部按钮标签。
让页面超过浏览器可视窗口高度。
设置顶部通栏样式,默认是在超出页面的。
设置回到顶部按钮样式,默认是在隐藏的。
代码逻辑
给浏览器绑定滚动事件,实时获取浏览器卷去的高度。
根据卷去的高度判断决定隐藏还是显示。
回到顶部按钮绑定点击事件。
<!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;
}
/* 页面设置高度,出现滚动条 */
body {
height: 3000px;
}
.header{
width: 100%;
height: 80px;
/* flex弹性布局方式 */
display: flex;
/* 水平主轴上对齐方式 */
justify-content: center;
/* 垂直交叉轴对齐方式 */
align-items: center;
font-size: 30px;
color: aliceblue;
background-color: black;
/* 过度持续时间:过度线性规律:匀速 */
transition: top .5s linear;
/* postion属性:将元素从页面流中分离出来
,然后设定具体的位置,
从而实现更加精确的定位。
relative,相对于自身进行定位,
absolute,绝对定位,遗留下来的快捷由后面元素填充。
定位起始位置为最近的父元素(position非静态,
否则为Body坐标原点,
和页面一起滚动。
fixed,固定定位,相对于浏览器窗口进行定位,
可通过z-index分级 */
position: fixed;
/* 定位在页面之外,若卷去高度大于300,top=0px */
top: -80px;
left: 0;
}
.goTop {
width: 50px;
height: 50px;
background-color: rgb(228, 131, 131);
font-size: 20px;
/* 文本的位置 */
text-align: center;
/* 两行基线之间的距离就是行高,
行距是上底线和下底线的距离
行距=行高-字体大小 */
line-height: 25px;
color: blanchedalmond;
position: fixed;
bottom: 50px;
right: 50px;
/* 隐藏元素并脱离文档流,卷去高度大于300,则display变成block */
display: none;
}
</style>
</head>
<body>
<div class="header">顶部通栏</div>
<div class="goTop">回到顶部</div>
<script>
// 1.获取元素
var header = document.querySelector('.header')
var goTop = document.querySelector('.goTop')
// 2.绑定滚动事件
window.onscroll = function(){
// 2-1 获取浏览器卷去的高度,即有滚动条时,页面隐藏的部分尺寸。
var height = document.documentElement.scrollTop || document.body.scrollTop
// 2.2 判断卷去的高度
if(height>=300){
// 显示
header.style.top = '0px'
goTop.style.display = 'block'
}else{
// 隐藏
header.style.top = '-80px'
goTop.style.display = 'none'
}
}
// 3.绑定点击事件
goTop.onclick = function(){
// 3.1 让页面滚动回到顶部
// top等同于y-coord,left等同于x-coord,behavior表示滚动的行为,
// 支持参数smooth(平滑滚动)
window.scrollTo({
top: 0,
behavior:'smooth'
})
}
</script>
</body>
</html>
案例:全选
确定需求:
1.若子按钮全选中,则选中全选按钮。
当按下一个子按钮则判断四个按钮是否全选中。
2.当按下全选中按钮,则判断是否子按钮全选中,其中未选中的进行勾选。
布局要求:
只需一个全选按钮若干子按钮。
代码逻辑:
1.给全选按钮绑定点击事件。
拿到全选按钮的选中状态,给所有子按钮设置选中状态。
2.当有一个子按钮未被按下,则全选按钮为未选中状态。
<!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{
width: 100px;
padding: 20px;
/* dashed:虚线样式 solid:实线样式 */
border: 1px solid blueviolet;
/* 外边距实现居中 */
margin: 150px auto;
/* 圆角样式 */
border-radius: 50px;
}
hr{
margin: 10px auto;
}
</style>
</head>
<body>
<!-- 准备一个div包括所有按钮 -->
<div class="box">
全选:<input type="checkbox"><br>
<hr>
<input type="checkbox"> 选项1 <br>
<input type="checkbox"> 选项2 <br>
<input type="checkbox"> 选项3 <br>
<input type="checkbox"> 选项4 <br>
</div>
<script>
// 1.获取元素
var allbtn = document.querySelector('input')
// :nth-child(n)选择器匹配属于其父元素的第N个子元素,不论元素的类型.
// n+2从第二个开始
var items = document.querySelectorAll('input:nth-child(n+2)')
// console.log(allbtn)
// console.log(items)
// 2.给全选按钮绑定事件
allbtn.onclick = function(){
// 2.1 拿到选中状态
var type = allbtn.checked
// console.log(type)
// 2.2 把自己的选中状态设置给每一个选项按钮
for (var i = 0; i < items.length; i++){
items[i].checked = type
}
}
// 3.用循环给子按钮绑定点击事件
for (var i = 0; i < items.length; i++){
items[i].onclick = function(){
// 3.1 定义假设变量,假设所有按钮都是选中的
var flag = true
// 3.2 通过循环验证假设
for (var j = 0; j < items.length; j++){
// 只要有一个box是false ,flag为false
if(items[j].checked == false){
flag = false
break
}
}
// console.log(flag)
allbtn.checked = flag
}
}
// items.onclick = function(){
// var i1 = items.checked
// console.log(i1)
// if (i1,i2,i3,i4 = true){
// allbtn = true
// }
// }
// items[1].onclick = function(){
// var i2 = items[1].checked
// // console.log(i1)
// }
// items[2].onclick = function(){
// var i3 = items[3].checked
// // console.log(i1)
// }
// items[3].onclick = function(){
// var i4 = items[4].checked
// // console.log(i1)
// }
</script>
</body>
</html>
案例:选项卡
需求:
1.所选按钮高亮,其他回归原始
2.所选模块显示
结构布局
三个表示按钮的盒子,横向排列,初始一个高亮。
三个显示内容的盒子,在同一位置不同层级显示,初始一个显示。
代码逻辑
1.每一个按钮盒子绑定一个点击事件
2.点击任何一个按钮盒子时,所有按钮盒子取消高亮状态,所有内容盒子隐藏
3.点击任何一个按钮盒子时,当前按钮盒子高亮。当前索引对应的内容盒子显示。
<!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>
/* 清楚基本样式和UL li的样式 */
* {
margin: 0;
padding: 0;
}
ul,ol,li {
list-style: none;
}
/* 盒子样式,居中,有边框 */
.box {
width: 600px;
height: 400px;
border: 3px solid pink;
margin: 50px auto;
display: flex;
/* 列 */
flex-direction: column;
}
/* 子结合符,子元素选择器,
选择作为 box 元素子元素的所有 ul 元素,三个按钮横向排列, */
.box > ul {
height: 60px;
display: flex;
}
/* 居中, */
.box > ul > li {
/* 页面自适应伸缩比例值,在设置多个值的情况下比例起作用 */
flex: 1;
color: red;
background-color: royalblue;
font-size: 30px;
display: flex;
justify-content: center;
align-items: center;
/* 光标,一只手 */
cursor: pointer;
}
.box > ul >li.active{
background-color: salmon;
}
/* 显示内容的盒子,同一位置,不同层级*/
.box > ol {
flex: 1;
position: relative;
}
.box > ol > li {
width: 100%;
height: 100%;
background-color: blue;
display: flex;
justify-content: center;
align-items: center;
color: snow;
font-size: 100px;
position: absolute;
left: 0;
top: 0;
display: none;
}
.box > ol > li.active {
display: flex;
}
</style>
</head>
<!-- 页面布局的书写 -->
<body>
<!-- .box -->
<!-- <div class="box"> -->
<!-- ul>li*3{$} -->
<!-- <ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div> -->
<div class="box">
<!-- ul下三个li表示三个按钮盒子,ol下三个li表示三个切换内容的盒子 -->
<ul>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
<ol>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ol>
</div>
<script>
// 1.获取元素
var btns = document.querySelectorAll('ul>li')
var tabs = document.querySelectorAll('ol>li')
// 2.给btns里所有按钮添加点击事件
btns.forEach(function(item,index){
item.onclick = function(){
// 点击的按钮的标签状态
// console.log(item)
// 点击的按钮索引
// console.log(index)
// 2.1 给btns和tabs里面的所有内容取消 active 类名
btns.forEach(function(t,i){
// ul中所有的标签状态
// console.log(t)
// <li class="active">1</li>
// <li class>2</li>
// <li class>3</li>
// console.log(i)
// 0
// 1
// 2
t.className = ''
tabs[i].className = ''
})
// 2.2 当前点击的按钮和索引对应的盒子添加 active 类名
item.className = 'active'
tabs[index].className = 'active'
}
})
</script>
</body>
</html>
节点操作
创建节点:
…
案例:动态渲染数据
逻辑:
数据写到页面中:循环遍历user数组,有多少个成员执行多少回。
1.创建一个tr标签
2.循环遍历users内的每一个对象,对象内有多少个成员就执行多少遍.(1)创建一个td标签(2)向td标签内添加内容(3)把td标签插入到tr标签内
3.把tr插入到tbody内部
好处:
数组不用提前写好,在服务器端获取数组后就可以直接在页面显示更新数据了。
<!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>
table {
width: 300px;
text-align: center;
}
</style>
</head>
<body>
<!-- cellspacing单元格之间的空间 -->
<table border="1" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>性别</th>
</tr>
</thead>
<tbody>
<!-- js渲染 -->
</tbody>
</table>
<script>
// 提前准备数据
var users = [
{ id:1,name:'刚刚',age:18},
{ id:2,name:'笑笑',age:158},
{ id:3,name:'柳柳',age:185},
]
// 0.获取tbody标签
var tbody = document.querySelector('tbody')
// 1.循环遍历users数据
users.forEach(function(item){
// item是数组中每一个对象
console.log(item)
// 2.每一个对象生成一个tr标签
var tr = document.createElement('tr')
// 3.循环遍历item
for (var key in item){
// 4.生成td标签
var td = document.createElement('td')
td.innerHTML = item[key]
// 5.把td插入到tr标签内部
tr.appendChild(td)
}
tbody.appendChild(tr)
})
</script>
</body>
</html>
事件绑定
三要素:
事件源,事件类型,事件处理函数
语法:事件源.on事件类型=事件处理函数
事件对象:
当事件触发的时候,一个描述该事件信息的对象数据类型。——浏览器会以一个对象数据类型来记录下每次事件触发的时候一些相关信息。
拿到对象:
在绑定事件的时候,直接在事件处理函数内接收形参就可以了。
直接在事件处理函数接受形参
div.onclick = function(e){
console.log(e)
}
在事件触发的时候由浏览器自动传递实参,浏览器所传递的实参就是本次事件的事件对象。
案例:鼠标跟随
<!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>
img {
width: 50px;
height: 50px;
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<img src="../004/女孩.png">
<script>
var imgBox = document.querySelector("img")
document.onmousemove = function(e){
// console.log("dhh")
// 拿到光标相对于窗口的坐标点位
var x = e.clientX
var y = e.clientY
// console.log(x,y)
// 把x和y的值赋值给img标签的left和top样式
imgBox.style.left = x + 'px'
imgBox.style.top = y +'px'
}
</script>
</body>
</html>
事件传播
浏览器响应事件的机制
准确触发事件的元素:事件目标
从window到目标这个阶段叫做事件捕获阶段。
而从目标再次传递到window的阶段,叫做事件的冒泡阶段。
(浏览器窗口事先知道事件的发生)
阻止事件传播:
事件委托
案例:轮播图:
布局结构:
需求:
点击左按钮,当前消失,上一张出现
点击右按钮,当前消失,下一张出现
点击焦点,当前消失,某张出现