第一章:元素偏移量offset系列
1.1 offset概述
- offset翻译过来就是偏移量,我们使用offset系列相关属性可以
动态的
得到该元素的位置(偏移)、大小等。- offset可以获得元素距离带有定位的父元素的位置。
- offset可以获取元素自身的大小(宽度和高度)。
注意:offset返回的数值是不带单位的。
- offset系列属性: | offset系列属性 | 作用 | | —- | —- | | element.offsetParent | 返回作为该元素带有定位的父级元素,如果父级都没有定位,则返回body。 | | element.offsetTop | 返回元素相对带有定位元素上方的偏移量。 | | element.offsetLeft | 返回元素相对带有定位元素左边框的偏移量。 | | element.offsetWidth | 返回自身包括padding、边框、内容区的宽度,返回数值不带单位。 | | element.offsetHeight | 返回自身包括padding、边框、内容区的高度,返回数值不带单位。 |
- 示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>offset系列属性</title>
<style>
* {
margin: 0;
padding: 0;
}
.father {
width: 200px;
height: 200px;
background-color: pink;
margin: 150px;
}
.son {
width: 100px;
height: 100px;
background-color: red;
margin-left: 45px;
}
</style>
<script>
window.addEventListener('load', function (event) {
// offset系列
var father = document.querySelector('.father');
//可以得到元素的偏移,位置,返回不带单位的数值。
console.log(father.offsetLeft);// 返回元素相对带有定位元素左边框的偏移量。 150
console.log(father.offsetTop); // 返回元素相对带有定位元素上方的偏移量。 150
var son = document.querySelector('.son');
//以带有定位的父级元素为准,如果没有父级元素或父级元素没有定位,则以body为准
console.log(son.offsetLeft); // 195
console.log(son.offsetTop); // 150
//可以得到元素的大小:宽度(包括width、padding和border)和高度(包括height、padding和border)
console.log(father.offsetWidth); //200
console.log(father.offsetHeight); //200
//返回带有定位的父级元素,如果没有父级元素,则返回body。
console.log(son.offsetParent);
console.log(father.offsetParent);
});
</script>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
1.2 offset VS style
1.2.1 offset
- offset可以得到任意样式表中的样式值。
- offset系列获得的数值是没有单位的。
- offsetWidth包含padding、border和width。
- offsetWidth等属性是只读属性,只能获取不能赋值。
总结:想要获取元素大小位置,用offset更适合。
1.2.2 style
- style只能得到行内样式表中的样式值。
- style.width获得的是带有单位的字符串。
- style.width不包含padding和border的值。
- style.width是可读写属性,可以获取也可以赋值。
总结:想要给元素修改值,需要用style改变。
第二章:元素可视区client系列
client
翻译过来就是客户端,我们使用client系统的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。 | client系列属性 | 说明 | | —- | —- | | element.clientTop | 返回元素上边框的大小 | | element.clientleft | 返回元素左边框的大小 | | element.clientWidth | 返回自身包括padding、内容区的宽度,不包含边框,返回数值不带单位 | | element.clientHeight | 返回自身包括padding、内容区的高度,不包含边框,返回数值不带单位 |
- 示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>client系列</title>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
border: 10px solid red;
}
</style>
<script>
/* client宽度和offsetWidth的最大区别就是不包含边框 */
window.addEventListener('load', function () {
var div = document.querySelector('div');
console.log(div.clientTop); //10
console.log(div.clientLeft); //10
console.log(div.clientWidth); //200
console.log(div.clientHeight); //200
})
</script>
</head>
<body>
<div></div>
</body>
</html>
第三章:元素滚动scroll系列
3.1 元素scroll系统属性和事件
scroll
翻译过来就是滚动,我们使用scroll系列的相关属性可以动态的获取该元素的大小、滚动的距离等。 | scroll系列属性 | 说明 | | —- | —- | | element.scrollTop | 返回被卷去的上侧距离,返回的数值不带单位 | | element.scrollLeft | 返回被卷去的左侧距离,返回的数值不带单位 | | element.scrollWidth | 返回自身实际的宽度,不含边框,返回的数值不带位置。 | | element.scrollHeight | 返回自身实际的高度,不含边框,返回的数值不带位置。 |
如果浏览器的高(或宽)度不足以显示整个页面的时候,会自动出现滚动条。当滚动条向下滚动的时候,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动的时候会触发onscroll事件。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>scroll系列属性</title>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
border: 10px solid red;
padding: 10px;
overflow: auto;
}
</style>
<script>
window.addEventListener('load', function () {
var div = document.querySelector('div');
console.log(div.scrollWidth); //220 返回自身实际的宽度
console.log(div.scrollHeight); //220 返回自身实际的宽度
//scroll滚动时间,当滚动条发生变化的时候会触发的事件
div.addEventListener('scroll', function () {
console.log(div.scrollTop);
})
})
</script>
</head>
<body>
<div>
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
</div>
</body>
</html>
- 示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>仿淘宝固定侧边栏</title>
<style>
.w {
width: 1200px;
margin: 10px auto;
}
.header {
height: 150px;
background-color: purple;
}
.banner {
height: 250px;
background-color: skyblue;
}
.main {
height: 1000px;
background-color: yellowgreen;
}
.slider-bar {
position: absolute;
left: 50%;
top: 300px;
margin-left: 600px;
width: 45px;
height: 130px;
background-color: pink;
}
span {
display: none;
position: absolute;
bottom: 0;
}
</style>
<script>
window.addEventListener('load', function () {
var sliderBar = document.querySelector('.slider-bar');
var sliderBarTop = sliderBar.offsetTop;
var banner = document.querySelector('.banner');
var bannerTop = banner.offsetTop;
var main = document.querySelector('.main');
var mainTop = main.offsetTop;
var goBack = document.querySelector('.goBack');
document.addEventListener('scroll', function () {
//页面被卷去的头部
// console.log(window.pageYOffset)
// 当页面被卷去的头部>=170px,侧边栏就改为固定定位
if (window.pageYOffset >= bannerTop) {
sliderBar.style.position = 'fixed';
sliderBar.style.top = sliderBarTop - bannerTop + 'px';
} else {
sliderBar.style.position = 'absolute';
sliderBar.style.top = sliderBarTop + 'px';
}
if (window.pageYOffset >= mainTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none';
}
})
})
</script>
</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>
</body>
</html>
3.2 页面被卷去的头部兼容性解决方案
- 需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常由如下的几种写法:
- 声明了DTD,使用
document.documentElement.scrollTop
。 - 没有声明DTD,使用
document.body.scrollTop
。 - 新方法
window.pageYOffset
和window.pageXOffset
,IE9+才开始支持。
- 声明了DTD,使用
- 解决方案:
function getScroll() {
return {
left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0,
top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
};
}
//使用
getScroll().left
第四章:三大系列总结
三大系列大小对比 | 说明 |
---|---|
element.offsetWidth | 返回自身包含padding、边框、内容区的宽度,返回数值不带单位 |
element.clientWidth | 返回自身包含padding、内容区的宽度,不包含边框,返回数值不带单位 |
element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
主要用法:
- offset系列经常用于获取元素的位置:offsetLeft、offsetTop。
- client系列经常用于获取元素的大小:clientLeft、clientTop。
- scroll系列经常有用于获取滚动距离:scrollLeft、scrollTop。
- 注意页面滚动的距离通过window.pageXoffset获取。
第五章:mouseover和mouseenter的区别
- 当鼠标移动到元素上的时候就会触发mouseenter(对应的事件是mouseleave)和mouseover事件(对应的事件是mouseout)。
- mouseover鼠标经过自身盒子会触发事件,经过子盒子也会触发事件。
mouseenter鼠标经过自身盒子才会触发事件,经过子盒子不会触发事件。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>mouseover和mouseenter</title>
<style>
* {
margin: 0;
padding: 0;
}
.father {
position: relative;
width: 200px;
height: 200px;
background-color: pink;
margin: 100px auto;
}
.son {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
background-color: red;
}
</style>
<script>
window.addEventListener('load', event => {
var father = document.querySelector('.father');
var son = document.querySelector('.son');
father.addEventListener('mouseover', function () {
console.log(11);
})
father.addEventListener('mouseenter', function () {
console.log(22);
})
});
</script>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
第六章:动画函数的封装
6.1 动画实现原理
核心原理
:通过定时器setInterval()不断移动盒子位置。实现步骤:
- ①获取盒子当前位置。
- ②让盒子在当前位置加上1个移动距离。
- ③利用定时器不断重复这个操作。
- ④加一个结束定时器的条件。
- ⑤注意此元素需要添加定位,才能使用
element.style.left
。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>动画原理</title>
<style>
div {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
/*
* 核心原理:通过定时器 setInterval() 不断移动盒子位置。
* 实现步骤:
* 1. 获得盒子当前位置
* 2. 让盒子在当前位置加上1个移动距离
* 3. 利用定时器不断重复这个操作
* 4. 加一个结束定时器的条件
* 5. 注意此元素需要添加定位,才能使用element.style.left
*/
var div = document.querySelector('div');
var timer = setInterval(function () {
if (div.offsetLeft >= 400) {
//停止动画 本质是停止定时器
clearInterval(timer);
}
div.style.left = div.offsetLeft + 1 + 'px';
}, 30);
</script>
</body>
</html>
6.2 动画函数的简单封装
注意函数需要传递2个参数,
动画对象
和移动到的距离
。示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>动画函数简单封装</title>
<style>
div {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
/*
* 核心原理:通过定时器 setInterval() 不断移动盒子位置。
* 实现步骤:
* 1. 获得盒子当前位置
* 2. 让盒子在当前位置加上1个移动距离
* 3. 利用定时器不断重复这个操作
* 4. 加一个结束定时器的条件
* 5. 注意此元素需要添加定位,才能使用element.style.left
*/
function animation(ele, left) {
var timer = setInterval(function () {
if (ele.offsetLeft >= left) {
//停止动画 本质是停止定时器
clearInterval(timer);
}
ele.style.left = ele.offsetLeft + 1 + 'px';
}, 30);
}
var div = document.querySelector('div');
animation(div, 400);
</script>
</body>
</html>
6.3 动画函数给不同元素记录不同定时器
- 如果多个元素都使用这个动画函数,每次都要var声明定时器。我们可以给不同的元素使用不同的定时器。
核心原理:利用JS是一门动态语言,可以很方便的给当前对象添加属性。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>动画函数给不同元素记录不同定时器</title>
<style>
div {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: pink;
margin-top: 100px;
}
</style>
</head>
<body>
<button>点击我,才开始走</button>
<div></div>
<script>
function animation(ele, left) {
//当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
//解决方案:让我们元素只有一个定时器即可。
clearInterval(ele.timer);
ele.timer = setInterval(function () {
if (ele.offsetLeft >= left) {
//停止动画 本质是停止定时器
clearInterval(ele.timer);
}
ele.style.left = ele.offsetLeft + 1 + 'px';
}, 30);
}
var div = document.querySelector('div');
var button = document.querySelector('button');
button.addEventListener('click', function () {
animation(div, 400);
})
</script>
</body>
</html>