offset家族
作用
获取元素 ‘自身’ 宽高与位置
- 元素.offsetWidth / 元素.offsetHeight
- width+padding+border
- 元素.offsetLeft / 元素.offsetTop
- 自身 到 定位父元素 左/上 内边框距离 示例如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<title>标题</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 150px;
height: 150px;
background-color: pink;
overflow: auto;
padding: 10px;
border: 10px solid red;
margin: 100px;
}
</style>
</head>
<body>
<div class="box">
我有很多很多的内容哦 我有很多很多的内容哦 我有很多很多的内容哦
我有很多很多的内容哦 我有很多很多的内容哦 我有很多很多的内容哦
我有很多很多的内容哦 我有很多很多的内容哦 我有很多很多的内容哦
我有很多很多的内容哦 我有很多很多的内容哦 我有很多很多的内容哦
我有很多很多的内容哦 我有很多很多的内容哦 我有很多很多的内容哦
</div>
<script>
let box = document.querySelector('.box')
//三大家族是dom语法,不是css样式。
//错误写法: 元素.style.offsetWidth
//正确写法: 元素.offsetWidth
// 1. offset家族
console.log(box.offsetWidth, box.offsetHeight)// 190 190
console.log(box.offsetLeft, box.offsetTop)// 100 100
//2. scroll家族
console.log( box.scrollWidth , box.scrollHeight )//153 419
console.log( box.scrollLeft , box.scrollTop )//0 0 默认没有滚动
//3. client家族
console.log( box.clientWidth , box.clientHeight ) // 153 170
console.log( box.clientLeft , box.clientTop ) // 10 10
</script>
</body>
</html>
scroll家族
作用
获取元素 ‘内容’ 宽高与位置
- 元素.scrollWidth / 元素.scrollHeight
- 内容宽高
- 元素.scrollLeft / 元素.scrollTop
- 内容位置 : 滚动条滚动的距离 示例代码如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>标题</title>
<style>
body {
width: 3000px;
height: 3000px;
}
</style>
</head>
<body>
<script>
/* 获取网页滚动距离
1.给页面注册滚动事件 : window.onscroll
2.获取页面滚动距离 : document.documentElement.scrollTop
*/
//1.给页面注册滚动条事件 onscroll
window.onscroll = function () {
//2.获取页面滚动的距离 html标签的scrollTop
console.log(document.documentElement.scrollLeft, document.documentElement.scrollTop)
}
</script>
</body>
</html>
应用
案例示例如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0
}
img {
vertical-align: top;
}
.main {
margin: 0 auto;
width: 1000px;
margin-top: 10px;
}
.fixed {
position: fixed;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div class="top" id="topPart">
<img id="pic" src="images/top.png" alt=""/>
</div>
<div class="nav" id="navBar">
<img src="images/nav.png" alt=""/>
</div>
<div class="main" id="mainPart">
<img src="images/main.png" alt=""/>
</div>
<script>
/* 思路
1. 注册页面滚动事件 : 判断 页面滚动距离 与 top盒子高度 关系
(1)如果 页面距离 >= 盒子高度 : 设置导航盒子nav为固定定位 (添加类名fixed)
(2)否则 : 设置导航盒子nav为标准流(移除类名fixed)
*/
//1.获取元素
let topPart = document.querySelector('.top')
let navBar = document.querySelector('.nav')
let mainPart = document.querySelector('.main')
//2.给页面注册滚动事件
window.onscroll = function(){
//3.判断页面滚动距离 与 topPart高度关系
if( document.documentElement.scrollTop >= topPart.offsetHeight ){
navBar.classList.add('fixed')
/* 细节注意点: 固定定位会脱标,导致下面标准流瞬间闪上去(顿闪)
解决方案: 设置下面盒子的marginTop, 撑开脱标的高度
*/
mainPart.style.marginTop = 10 + navBar.offsetHeight + 'px'
}else{
navBar.classList.remove('fixed')
//回到标准流, marginTop也要恢复
mainPart.style.marginTop = 10 + 'px'
}
}
</script>
</body>
</html>
client家族
作用
获取元素 ‘可视区域’ 宽高与位置
- 元素.clientWidth / 元素clientHeight
- 视口大小
- 元素.clientLeft / 元素.clientTop
- 左边框和上边框宽度
应用
- 响应式(横竖屏适配) 示例如下:
<!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>
</head>
<body>
<script>
/* client家族应用 : 响应式布局
1.响应式布局 : 一个页面适配多个不同设备
2.响应式布局设备 :
大PC : >= 1200px
小pc,大平板 : 992px - 1200px
平板 : 768px - 992px
手机 : < 768px
3.响应式布局原理
3.1 监听设备视口大小 : 媒体查询、clientWidth
3.2 根据视口大小加载不同的样式
*/
//1.给页面注册视口大小变化 onresize
window.onresize = function(){
//2.获取视口大小 (页面可视区域大小)
let w = document.documentElement.clientWidth
let h = document.documentElement.clientHeight
console.log(w,h)
if( w >= 1200 ){
document.body.style.backgroundColor = 'red'
}else if( w >= 992 ){//隐藏条件 w < 1200
document.body.style.backgroundColor = 'orange'
}else if( w >= 768 ){//隐藏条件 w < 992
document.body.style.backgroundColor = 'yellow'
}else{//隐藏条件 w < 768
document.body.style.backgroundColor = 'green'
}
/* 横竖屏适配 */
if( w > h ){
alert('横屏')
}else{
alert('竖屏')
}
}
</script>
</body>
</html>
经典电梯导航案例
示例代码如下:
<!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>
* {
margin: 0;
padding: 0;
}
body {
height: 3000px;
}
.aside {
position: fixed;
left: 0;
top: 50%;
transform: translateY(-50%);
}
.item {
height: 40px;
line-height: 40px;
text-align: center;
padding: 0 10px;
cursor: pointer;
}
.active {
background-color: red;
color: #fff;
}
.content {
width: 660px;
margin: 400px auto;
}
.neirong {
height: 300px;
margin-bottom: 20px;
color: #fff;
}
.content1 {
background-color: red;
}
.content2 {
background-color: blue;
}
.content3 {
background-color: orange;
}
.content4 {
background-color: yellowgreen;
}
</style>
</head>
<body>
<div class="aside">
<div class="item active">男装/女装</div>
<div class="item">儿童服装/游乐园</div>
<div class="item">电子产品</div>
<div class="item">电影/美食</div>
</div>
<div class="content">
<div class="neirong content1">男装/女装</div>
<div class="neirong content2">儿童服装/游乐园</div>
<div class="neirong content3">电子产品</div>
<div class="neirong content4">电影/美食</div>
</div>
<script>
/* 思路分析
1.点击左侧每一个列表
1.1 排他思想修改样式 : 类名排他active
1.2 页面滚动到下标一致盒子位置 :
页面滚动 document.documentElement.scrollTop
盒子位置 neirongList[i].offsetTop
*/
//1.获取元素
let itemList = document.querySelectorAll('.aside>.item')//左侧列表
let neirongList = document.querySelectorAll('.content>.neirong')//左侧列表
//2.点击每一个列表
for (let i = 0; i < itemList.length; i++) {
itemList[i].onclick = function () {
//3.事件处理
//3.1 排他思想修改样式 : 类名排他active
//(1)干掉兄弟
document.querySelector('.item.active').classList.remove('active')
//(2)复活自己
this.classList.add('active')
//3.2 页面滚动到下标一致盒子的位置
document.documentElement.scrollTop = neirongList[i].offsetTop
}
}
/* 3. 页面滚动事件 : 当前显示的盒子对应下标 的 左侧列表高亮
左侧列表高亮 : 排他修改类型
显示的盒子对应下标 : 第一个比 页面滚动距离 大的盒子
*/
window.onscroll = function () {
//遍历盒子的scrollTop,找第一个比 页面滚动距离 大的盒子
for (let i = 0; i < neirongList.length; i++) {
// console.log(`页面滚动距离${document.documentElement.scrollTop}`)
// console.log(`第${i}个盒子位置${neirongList[i].offsetTop}` )
if (neirongList[i].offsetTop + 100 > document.documentElement.scrollTop) {
//排他修改左边下标的类名
document.querySelector('.item.active').classList.remove('active')
//复活i下标列表
itemList[i].classList.add('active')
//一旦找到第一个 位置 比 页面滚动距离大的盒子,就必须要break结束循环
break
}
}
}
</script>
</body>
</html>