Bom操作02

Bom操作

7. 立即执行函数

image-20230302163721008

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
// 1.立即执行函数: 不需要调用,立马能够自己执行的函数
function fn() {
console.log(1);
}
fn();

// 2. 写法 也可以传递参数进来

// 1.(function() {})()
(function(a, b) {
console.log(a + b)
var num = 10
})(1, 2);

// 第二个小括号可以看做是调用函数
// 2. (function(){}());
(function sum(a, b) {
console.log(a + b);
var num = 10; // 局部变量
}(2, 3));

// !!!:立即执行函数必须以';'结尾

// 3. 立即执行函数最大的作用就是 独立创建了一个作用域, 里面所有的变量都是局部变量 不会有命名冲突的情况
</script>

8. 边距与距离

8.1 元素偏移量 offset 系列

8.11 概述

image-20230302163954942

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<!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;
}
.dad{
position: relative;
width: 200px;
height: 200px;
background-color: blueviolet;
margin: 100px;
padding: 10px;border: 10px solid red;
}
.son{
width: 50px;
height: 50px;
background-color: rgb(252, 127, 2);
margin: 75px;
}
</style>
</head>
<body>
<div class="dad">
<div class="son"></div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function(e) {
// 1.1.1 offset 概述
// offset 翻译过来就是偏移量, 我们使用 offset系列相关属性可以动态的得到该元素的位置(偏
// 移)、大小等。
// 1. 获得元素距离带有定位父元素的位置
// 2. 获得元素自身的大小(宽度高度)
// 3. 注意:返回的数值都不带单位

var box=document.querySelector('.dad')
var son=document.querySelector('.son')

// offsetTop 返回元素相对带有定位父元素上方的偏移
// offsetLeft 返回元素相对带有定位父元素左边框的偏移
// offsetWidth 返回自身包括padding、边框、内容区的宽度,返回数值不带单位
// offsetHeight 返回自身包括padding、边框、内容区的高度,返回数值不带单位

// 1.可以得到元素的偏移位置,返回不带单位的数值
console.log(box.offsetTop)
console.log(box.offsetLeft)

// 它以带有定位的父亲为准,如果有父亲或者父亲没有定位,则以body为准
console.log(son.offsetTop)
console.log(son.offsetLeft)

// 2. 获得元素自身的大小(宽度高度)
console.log(box.offsetWidth)
console.log(box.offsetHeight)

// 3、获得元素距离带有定位父元素的位置
// 返回作为该元素带有定位的父级元素,如果父级都没有定位则返回body
console.log(son.offsetParent);
// 返回父亲最近一级的父亲,不管有没有定位
console.log(son.parentNode);

})
</script>
</body>
</html>

8.12 offset 与 style 区别

image-20230302164203827

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.box {
width: 200px;
height: 200px;
background-color: pink;
padding: 10px;
}
</style>
</head>

<body>
<div class="box" style="width: 200px;"></div>
<script>
// offset与style的区别
var box = document.querySelector('.box');
console.log(box.offsetWidth);
console.log(box.style.width);
// box.offsetWidth = '300px';
box.style.width = '300px';

// 1.1.2 offset 与 style 区别

// offset
// offset 可以得到任意样式表中的样式值
// offset 系列获得的数值是没有单位的
// offsetWidth 包含padding+border+width
// offsetWidth 等属性是只读属性,只能获取不能赋值
// !!!所以,我们想要获取元素大小位置,用offset更合适!!!

// style
// style 只能得到行内样式表中的样式值
// style.width 获得的是带有单位的字符串
// style.width 获得不包含padding和border 的值
</script>
</body>

</html>

8.13 案例

1. 获取鼠标在盒子里的距离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!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;
}

div {
margin: 200px;
width: 200px;
height: 200px;
background-color: blueviolet;
text-align: center;
line-height: 200px;
color: white;
}
</style>
</head>

<body>
<script>
// 1. 我们在盒子内点击,想要得到鼠标距离盒子左右的距离。
// 2. 首先得到鼠标在页面中的坐标(e.pageX, e.pageY)
// 3. 其次得到盒子在页面中的距离 ( box.offsetLeft, box.offsetTop)
// 4. 用鼠标距离页面的坐标减去盒子在页面中的距离,得到 鼠标在盒子内的坐标
// 5. 如果想要移动一下鼠标,就要获取最新的坐标,使用鼠标移动mousemove

document.addEventListener("DOMContentLoaded", function (e) {
var btn = document.querySelector('div')
btn.addEventListener("mousemove", function (e) {
var x = e.pageX
var y = e.pageY
var left = btn.offsetLeft
var top = btn.offsetTop
var resultX = x - left
var resultY = y - top
console.log(resultX + ',' + resultY);
})

btn.addEventListener('mousemove', function (e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
this.innerHTML = 'x坐标是' + x + ' y坐标是' + y;
})
})



</script>
<div></div>
</body>

</html>

2. 模态框拖拽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!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;
}

h2 {
text-align: center;
display: block;
}

.login {
display: none;
width: 500px;
height: 300px;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
box-shadow: 0px 0px 6px 0px rgb(255, 255, 255);
background-color: #fff;
z-index: 1;
}

h1 {
text-align: center;
margin: 20px 0 20px;
cursor: all-scroll;
}

.close {
width: 50px;
height: 50px;
display: block;
border-radius: 50%;
text-align: center;
line-height: 50px;
position: absolute;
top: -25px;
right: -25px;
cursor: pointer;
box-shadow: 0px 0px 6px 0px rgb(194, 190, 190);
background-color: #fff;
}

form {
margin: 10px 40px;
height: 200px;
}

.name,
.psd {
padding: 5px;
width: 300px;
height: 30px;
margin: 0 0 30px;
border: 1px solid #ccc;
background-color: #fff;
}

.btn {
width: 200px;
height: 40px;
border: 1px solid #ccc;
background-color: #fff;
cursor: pointer;
margin: 0 auto;
display: block;

color: black;
text-decoration: none;
text-align: center;
line-height: 40px;
}

.shadow {
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .4);
}
</style>
</head>

<body>
<h2 style="cursor: pointer;">click</h2>
<div class="login">
<h1>Login</h1>
<form action="" method="get">
username:<input class="name" type="text" name="username" placeholder="username" value="">
<br />
password:<input class="psd" type="password" name="password" placeholder="password" value="">
<br />
<!-- <button class="btn" type="submit">Submit</button> -->
<a href="javascript:;" class="btn">Submit</a>
</form>
<span class="close">close</span>
</div>
<div class="shadow"></div>
<script>
// 1.1.4 案例:模态框拖拽
// 弹出框,我们也称为模态框。
// 1.点击弹出层,会弹出模态框, 并且显示灰色半透明的遮挡层。
// 2.点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层。
// 3.鼠标放到模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动。
// 4.鼠标松开,可以停止拖动模态框移动

// 1.1.5. 案例分析:
// 1. 点击弹出层, 模态框和遮挡层就会显示出来 display:block;
// 2. 点击关闭按钮,模态框和遮挡层就会隐藏起来 display:none;
// 3. 在页面中拖拽的原理:鼠标按下并且移动, 之后松开鼠标
// 4. 触发事件是鼠标按下mousedown,鼠标移动mousemove 鼠标松开 mouseup
// 5. 拖拽过程: 鼠标移动过程中,获得最新的值赋值给模态框的left和top值,这样模态框可以跟着
// 鼠标走了
// 6. 鼠标按下触发的事件源是最上面一行,就是 id 为 title
// 7. 鼠标的坐标减去 鼠标在盒子内的坐标, 才是模态框真正的位置。
// 8. 鼠标按下,我们要得到鼠标在盒子的坐标。
// 9. 鼠标移动,就让模态框的坐标 设置为 :鼠标坐标 减去盒子坐标即可,注意移动事件写到按下
// 事件里面。
// 10. 鼠标松开,就停止拖拽,就是可以让鼠标移动事件解除

document.addEventListener("DOMContentLoaded", function (e) {
var h1 = document.querySelector('h1')
var h2 = document.querySelector('h2')
var login = document.querySelector('.login')
var close = document.querySelector('.close')
var shadow = document.querySelector('.shadow')

h2.addEventListener('click', function () {
shadow.style.position = 'fixed'
login.style.display = 'block'
})

close.addEventListener('click', function () {
shadow.style.position = ''
login.style.display = ''
})

// 开始拖拽
h1.addEventListener('mousedown', function (e) {
// (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;

// (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
document.addEventListener('mousemove', move)

function move(e) {
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
}

// (3) 鼠标弹起,就让鼠标移动事件移除
document.addEventListener('mouseup', function () {
document.removeEventListener('mousemove', move);
})

})
})
</script>
</body>

</html>

3. 京东放大镜

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<!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;
}

.view {
display: flex;
justify-content: space-between;
width: 420px;
margin: 250px auto;
}

.left {
width: 200px;
height: 200px;
border: 1px solid brown;
position: relative;
cursor: all-scroll;
}

.left img {
width: 100%;
}

.right {
width: 200px;
height: 200px;
border: 1px solid brown;
overflow: hidden;
position: relative;
display: none;
}

.right img {
width: 200%;
position: absolute;
top: 0;
left: 0;
}

.shadow {
display: none;
width: 100px;
height: 100px;
position: absolute;
top: 0;
left: 0;
background: #FEDE4F;
opacity: .5;
border: 1px solid #ccc;
box-sizing: border-box;
cursor: move;
}
</style>
</head>

<body>
<div class="view">
<div class="left">
<img src="./images/s3.png" alt="" srcset="">
<div class="shadow"></div>
</div>
<div class="right">
<img src="./images/big.jpg" alt="" srcset="" class="phone">
</div>
</div>
<script>
// 1.1.6 案例:仿京东放大镜
// 1. 整个案例可以分为三个功能模块
// 2. 鼠标经过小图片盒子, 黄色的遮挡层 和 大图片盒子显示,离开隐藏2个盒子功能
// 3. 黄色的遮挡层跟随鼠标功能。
// 4. 移动黄色遮挡层,大图片跟随移动功能。

// 1.1.7. 案例分析:
// 1. 黄色的遮挡层跟随鼠标功能。
// 2. 把鼠标坐标给遮挡层不合适。因为遮挡层坐标以父盒子为准。
// 3. 首先是获得鼠标在盒子的坐标。
// 4. 之后把数值给遮挡层做为left 和top值。
// 5. 此时用到鼠标移动事件,但是还是在小图片盒子内移动。
// 6. 发现,遮挡层位置不对,需要再减去盒子自身高度和宽度的一半。
// 7. 遮挡层不能超出小图片盒子范围。
// 8. 如果小于零,就把坐标设置为0
// 9. 如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离
// 10. 遮挡层的最大移动距离:小图片盒子宽度 减去 遮挡层盒子宽度

document.addEventListener("DOMContentLoaded", function () {
var left = document.querySelector('.left')
var mask = document.querySelector('.shadow')
var right = document.querySelector('.right')
var bigIMg = document.querySelector('.phone')

left.addEventListener("mouseover", function () {
right.style.display = 'block'
mask.style.display = 'block'

})

left.addEventListener("mouseout", function () {
right.style.display = ''
mask.style.display = 'none'

})

left.addEventListener("mousemove", function (e) {
// (1) 当我们鼠标经过, 就获得鼠标在盒子内的坐标
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
// console.log(x + ' ' + y);


// (2) 减去盒子高度 100的一半 是 50 就是我们mask 的最终 left 和top值了
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;

// (3) 如果x 坐标小于了0 就让他停在0 的位置
// 遮挡层的最大移动距离
var maskMax = this.offsetWidth - mask.offsetWidth;
console.log(maskMax);

if (maskX <= 0) {
maskX = 0;
} else if (maskX >= maskMax) {
maskX = maskMax;
}

if (maskY <= 0) {
maskY = 0;
} else if (maskY >= maskMax) {
maskY = maskMax;
}
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';


// 3.大图片最大移动距离
var bigMax = bigIMg.offsetWidth - right.offsetWidth;
// 大图片的移动距离 X Y
// 遮挡层移动距离 / 遮挡层的最大移动 = 大图片的移动距离 / 大图片最大移动距离
// 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
bigIMg.style.left = -bigX + 'px';
bigIMg.style.top = -bigY + 'px';
})
})
</script>
</body>

</html>

8.2 元素可视区 client 系列

8.21 概述

image-20230302164538205

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
border: 10px solid red;
padding: 10px;
}
</style>
</head>

<body>
<div></div>
<script>
// client 宽度 和我们offsetWidth 最大的区别就是 不包含边框
var div = document.querySelector('div');
console.log(div.clientWidth);
</script>
</body>

</html>

8.22 拓展案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<!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>
body {
height: 3000px;
}

* {
padding: 0;
margin: 0;
}

.round {
position: fixed;
top: 0;
left: 0;
width: 30px;
height: 30px;
border: 1px solid #ccc;
box-sizing: border-box;
border-radius: 50%;
display: flex;
justify-content: space-around;
align-items: center;
z-index: -1;
}

.dot {
width: 10px;
height: 10px;
background-color: rgba(0, 0, 0, 0.478);
border-radius: 50%;
transition: all .1s;
}

.big {
width: 100%;
height: 100%;
}
</style>
</head>

<body>
<div class="round">
<div class="dot"></div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
var round = document.querySelector('.round')
var dot = document.querySelector('.dot')
// var box=document.createComment('div')
// var round = document.createElement('div')
// var dot = document.createElement('div')
// box.className='box'
// round.className = 'round'
// dot.className = 'dot'
// round.appendChild(dot)
// document.body.appendChild(round)
// console.log(round);

document.addEventListener('mousemove', function (e) {
// clientX 浏览器窗口可视区的X坐标
// clientY 浏览器窗口可视区的Y坐标
var x = e.clientX - round.offsetWidth / 2
var y = e.clientY - round.offsetHeight /2
round.style.left = x + 'px'
round.style.top = y + 'px'
// round.style.transform='translate(' + x + 'px'+','+y + 'px'+')'

this.addEventListener('mousedown', move)
function move() {
dot.className = 'dot big'
}

this.addEventListener('mouseup', movee)
function movee() {
dot.className = 'dot'
}
})

if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
// window.location.href = "../H5/index.html"; //手机
round.style.display = 'none'
console.log('7878');
}
})
</script>
</body>

</html>

8.3 元素滚动 scroll 系列

8.31 概述

image-20230302164912157

image-20230302165007813

image-20230302165026464

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<!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>
div {
width: 200px;
height: 200px;
background-color: pink;
padding: 10px;
border: 10px solid brown;
overflow-y: scroll;
}
</style>
</head>

<body>
<div>
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
content
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
var content = document.querySelector('div')
// scroll系列
// scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。

// element.scrollTop返回被卷去的上侧距离,返回数值不带单位
console.log('top:'+content.scrollTop)

// element.scrollLeft返回被卷去的左侧距离,返回数值不带单位
console.log('left:'+content.scrollLeft)

// element.scrollWidth返回自身实际的宽度,不含边框,返回数值不带单位
console.log('width:'+content.scrollWidth)

// element.scrollHeight返回自身实际的高度,不含边框,返回数值不带单位
console.log('height:'+content.scrollHeight)

// 滚动条在滚动时会触发 onscroll事件。
content.addEventListener('scroll', function(e){
console.log('scroll');
})

})
</script>
</body>

</html>

8.32 案例

1.仿淘宝固定右侧侧边栏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.slider-bar {
position: absolute;
right: 7%;
top: 300px;
width: 45px;
height: 130px;
background-color: pink;
}

.w {
width: 80%;
margin: 10px auto;
}

.header {
height: 150px;
background-color: purple;
}

.banner {
height: 250px;
background-color: skyblue;
}

.main {
height: 1000px;
background-color: yellowgreen;
}

span {
display: none;
position: absolute;
bottom: 0;
}
</style>
</head>

<body>
<div class="slider-bar">
<span class="goBack">返回顶部</span>
</div>
<div class="header w">头部区域</div>
<div class="banner w">banner区域</div>
<div class="main w">主体部分</div>
<script>
//1. 获取元素
var sliderbar = document.querySelector('.slider-bar');
var banner = document.querySelector('.banner');
var header = document.querySelector('.header');

// banner.offestTop 就是被卷去头部的大小 一定要写到滚动的外面
var bannerTop = banner.offsetTop
// 当我们侧边栏固定定位之后应该变化的数值
var sliderbarTop = sliderbar.offsetTop - bannerTop
// 获取main 主体元素
var main=document.querySelector('.main')
var goBack=document.querySelector('.goBack')
var mainTop = main.offsetTop

// 2. 页面滚动事件 scroll
document.addEventListener('scroll', function () {
// console.log(11);
// window.pageYOffset 页面被卷去的头部
// console.log(window.pageYOffset);
// 3 .当我们页面被卷去的头部大于等于了 172 此时 侧边栏就要改为固定定位
// 或者大于等于header.offsetHeight
if (window.pageYOffset >= bannerTop) {
sliderbar.style.position = 'fixed'
sliderbar.style.top = sliderbarTop+'px'
} else {
sliderbar.style.position = 'absolute'
sliderbar.style.top =''
}
// 4. 当我们页面滚动到main盒子,就显示 goback模块
if (window.pageYOffset >= mainTop) {
goBack.style.display='block'
} else {
goBack.style.display=''
}
})

// 案例:仿淘宝固定右侧侧边栏
// 1.原先侧边栏是绝对定位
// 2. 当页面滚动到一定位置,侧边栏改为固定定位
// 3. 页面继续滚动,会让 返回顶部显示出来

// 案例分析
// ① 需要用到页面滚动事件 scroll 因为是页面滚动,所以事件源是 document
// ② 滚动到某个位置,就是判断页面被卷去的上部值。
// ③ 页面被卷去的头部:可以通过window.pageYOffset 获得 如果是被卷去的左侧 window.pageXOffset
// ④ 注意,元素被卷去的头部是 element.scrollTop , 如果是页面被卷去的头部 则是 window.pageYOffset
// ⑤ 其实这个值 可以通过盒子的 offsetTop 可以得到,如果大于等于这个值,就可以让盒子固定定位了
</script>
</body>

</html>

2.右侧固定返回顶部案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<!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: 1000px;
}

div {
display: none;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: brown;
color: aliceblue;
text-align: center;
line-height: 50px;
position: fixed;
bottom: 50px;
right: 50px;
cursor: pointer;
}

p {
position: fixed;
bottom: 50px;
left: 50px;
}
</style>
</head>

<body>
<p></p>
<div title="返回顶部">up</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
var div = document.querySelector('div')
var p = document.querySelector('p')
document.addEventListener('scroll', function () {
if (window.pageYOffset >= 100) {
div.style.display = 'block'
p.innerHTML = window.pageYOffset
} else {
div.style.display = ''
p.innerHTML = ''
}
})
div.addEventListener('click', function () {
window.scroll(0, 0)
})
})
</script>
</body>

</html>

8.4 三大系列总结

image-20230302165359054

9. mouseenter 和mouseover的区别

image-20230302170019089

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.father {
width: 300px;
height: 300px;
background-color: pink;
margin: 100px auto;
}

.son {
width: 200px;
height: 200px;
background-color: purple;
}
</style>
</head>

<body>
<div class="father">
<div class="son"></div>
</div>
<script>
var father = document.querySelector('.father');
var son = document.querySelector('.son');
father.addEventListener('mouseenter', function() {
console.log(11);
son.innerHTML='11'
})
// 当鼠标移动到元素上时就会触发mouseenter 事件
// 类似 mouseover,它们两者之间的差别是
// mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发。
// mouseenter 只会经过自身盒子触发
// 之所以这样,就是因为mouseenter不会冒泡
// 跟mouseenter搭配鼠标离开 mouseleave 同样不会冒泡
</script>
</body>

</html>

10. 触屏事件

10.1概述

image-20230302170211459

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!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;
}

div {
width: 200px;
height: 200px;
background-color: blueviolet;
color: azure;
text-align: center;
line-height: 200px;
font-size: 20px;
}
</style>
</head>

<body>
<div></div>
<script>
var touchBox = document.querySelector('div')

// 手指触摸到一个DOM元素时触发
touchBox.addEventListener('touchstart', function () {
touchBox.innerHTML='手指触摸'
})

// 手指在一个DOM元素上滑动时触发
touchBox.addEventListener('touchmove', function () {
// touchBox.innerHTML='手指滑动'
console.log('手指滑动');
})

// 手指从一个DOM元素上移开时触发
touchBox.addEventListener('touchend', function () {
// touchBox.innerHTML='手指移开'
console.log('手指移开');
})

// 屏幕滑动检测
window.addEventListener('touchmove',function(){
console.log('屏幕滑动');
})
</script>
</body>

</html>

10.2 触摸事件对象(TouchEvent)

image-20230302170342861

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!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;
}

div {
width: 200px;
height: 200px;
background-color: blueviolet;
color: azure;
text-align: center;
line-height: 200px;
font-size: 20px;
}
</style>
</head>

<body>
<div></div>
<script>
// 触摸事件对象
// 1. 获取元素
// 2. 手指触摸DOM元素事件
var div = document.querySelector('div');
div.addEventListener('touchstart', function (e) {
// console.log(e);
// touches 正在触摸屏幕的所有手指的列表
// targetTouches 正在触摸当前DOM元素的手指列表
// 如果侦听的是一个DOM元素,他们两个是一样的
// changedTouches 手指状态发生了改变的列表 从无到有 或者 从有到无
// 因为我们一般都是触摸元素 所以最经常使用的是 targetTouches
console.log(e.targetTouches[0]);
// targetTouches[0] 就可以得到正在触摸dom元素的第一个手指的相关信息比如 手指的坐标等等
});
// 3. 手指在DOM元素身上移动事件
div.addEventListener('touchmove', function () {


});
// 4. 手指离开DOM元素事件
div.addEventListener('touchend', function (e) {
// console.log(e);
// 当我们手指离开屏幕的时候,就没有了 touches 和 targetTouches 列表
// 但是会有 changedTouches
});
</script>
</body>

</html>

10.3 移动端拖动案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<!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;
}

div {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 200px;
background-color: blueviolet;
color: azure;
text-align: center;
line-height: 200px;
font-size: 20px;
}
</style>
</head>

<body>
<div></div>
<script>
// (1) 触摸元素 touchstart: 获取手指初始坐标,同时获得盒子原来的位置
// (2) 移动手指 touchmove: 计算手指的滑动距离,并且移动盒子
// (3) 离开手指 touchend:
var div = document.querySelector('div');

//获取手指初始坐标
var fingerX = 0;
var fingerY = 0;

//获得盒子原来的位置
var boxX = 0;
var boxY = 0;

div.addEventListener('touchstart', function (e) {
// 获取手指在盒子上的坐标
fingerX = e.targetTouches[0].pageX
fingerY = e.targetTouches[0].pageY

// 获取盒子初始的坐标
boxX = this.offsetLeft
boxY = this.offsetTop
})

div.addEventListener('touchmove', function (e) {
// 计算手指的移动距离: 手指移动之后的坐标减去手指初始的坐标
var moveX = e.targetTouches[0].pageX - fingerX;
var moveY = e.targetTouches[0].pageY - fingerY;

// 移动我们的盒子 盒子原来的位置 + 手指移动的距离
this.style.left = boxX + moveX + 'px';
this.style.top = boxY + moveY + 'px';
this.innerHTML = 'x:' + this.style.left + ',y:' + this.style.top

// 阻止屏幕滚动的默认行为
e.preventDefault();
})
</script>
</body>

</html>

11. classList 属性

image-20230302170524222

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.bg {
background-color: black;
}
</style>
</head>

<body>
<div class="one two"></div>
<button> 开关灯</button>
<script>
// classList 返回元素的类名
var div = document.querySelector('div');
// console.log(div.classList[1]);
// 1. 添加类名 是在后面追加类名不会覆盖以前的类名 注意前面不需要加.
div.classList.add('three');
// 2. 删除类名
div.classList.remove('one');
// 3. 切换类
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
document.body.classList.toggle('bg');
})
</script>
</body>

</html>

12. 本地存储

12.1 概述

image-20230302170652533

12.2 分类

12.21 window.sessionStorage

image-20230302170705814

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<!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>
</head>

<body>
<input class="txt" type="text" name="" id="">
<button class="set">存储数据</button>
<button class="get">获取数据</button>
<button class="remove">删除数据</button>
<button class="delete">清空数据</button>

<script>
// 本地存储
// 随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样
// 的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。

// 本地存储特性
// 1、数据存储在用户浏览器中
// 2、设置、读取方便、甚至页面刷新不丢失数据
// 3、容量较大,sessionStorage约5M、localStorage约20M
// 4、只能存储字符串,可以将对象JSON.stringify() 编码后存储

document.addEventListener("DOMContentLoaded", function () {
var txtInput = document.querySelector('.txt');
var dataSet = document.querySelector('.set')
var dataGet = document.querySelector('.get')
var dataRemove = document.querySelector('.remove')
var dataDelete = document.querySelector('.delete')

// window.sessionStorage
// 1、生命周期为关闭浏览器窗口
// 2、在同一个窗口(页面)下数据可以共享
// 3、以键值对的形式存储使用

// 存储数据
dataSet.addEventListener('click', function () {
// 提取到文本框的数据
var dataTxt = txtInput.value
sessionStorage.setItem('uname', dataTxt)
sessionStorage.setItem('pwd', dataTxt)

})

// 获取数据
dataGet.addEventListener('click', function () {
sessionStorage.getItem('uname')
console.log(sessionStorage.getItem('uname'));
})

// 删除数据
dataRemove.addEventListener('click', function () {
sessionStorage.removeItem('uname')
})

// 清空数据
dataDelete.addEventListener('click', function () {
sessionStorage.clear()
})
})
</script>
</body>

</html>

12.22 window.localStorage

image-20230302170741832

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<!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>
</head>

<body>
<input class="txt" type="text" name="" id="">
<button class="set">存储数据</button>
<button class="get">获取数据</button>
<button class="remove">删除数据</button>
<button class="delete">清空数据</button>

<script>
// 本地存储
// 随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样
// 的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。

// 本地存储特性
// 1、数据存储在用户浏览器中
// 2、设置、读取方便、甚至页面刷新不丢失数据
// 3、容量较大,localStorage约5M、localStorage约20M
// 4、只能存储字符串,可以将对象JSON.stringify() 编码后存储

document.addEventListener("DOMContentLoaded", function () {
var txtInput = document.querySelector('.txt');
var dataSet = document.querySelector('.set')
var dataGet = document.querySelector('.get')
var dataRemove = document.querySelector('.remove')
var dataDelete = document.querySelector('.delete')

// 1、声明周期永久生效,除非手动删除 否则关闭页面也会存在
// 2、可以多窗口(页面)共享(同一浏览器可以共享)
// 3. 以键值对的形式存储使用

// 存储数据
dataSet.addEventListener('click', function () {
// 提取到文本框的数据
var dataTxt = txtInput.value
localStorage.setItem('uname', dataTxt)
localStorage.setItem('pwd', dataTxt)

})

// 获取数据
dataGet.addEventListener('click', function () {
localStorage.getItem('uname')
console.log(localStorage.getItem('uname'));
})

// 删除数据
dataRemove.addEventListener('click', function () {
localStorage.removeItem('uname')
})

// 清空数据
dataDelete.addEventListener('click', function () {
localStorage.clear()
})
})
</script>
</body>

</html>

12.3 记住用户案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!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>
</head>

<body>
<input type="text" name="" id="uname">
<input type="checkbox" name="" id="remember">
记住用户名
<script>
// 如果勾选记住用户名, 下次用户打开浏览器,就在文本框里面自动显示上次登录的用户名
// 案例分析
// 1. 把数据存起来,用到本地存储
// 2. 关闭页面,也可以显示用户名,所以用到localStorage
// 3. 打开页面,先判断是否有这个用户名,如果有,就在表单里面显示用户名,并且勾选复选框
// 4. 当复选框发生改变的时候change事件
// 5. 如果勾选,就存储,否则就移除

window.addEventListener('load', function () {
var uname = document.querySelector('#uname')
var remember = document.querySelector('#remember')

// 3. 打开页面,先判断是否有这个用户名,如果有,就在表单里面显示用户名,并且勾选复选框
if (localStorage.getItem('uname')) {
uname.value = localStorage.getItem('uname')
remember.checked = true
}

// 4. 当复选框发生改变的时候change事件
// 5. 如果勾选,就存储,否则就移除
remember.addEventListener('change', function () {
if (this.checked) {
localStorage.setItem('uname', uname.value)
} else {
localStorage.removeItem('uname')
}
})

})
</script>
</body>

</html>