快捷尺寸
有些元素样式,我们需要频繁使用,虽然可以使用元素.style.属性名
、window.getComputedStyle()
或者currentStyle属性
获取,但是很显然这样会很麻烦,所以浏览器提供了一些快捷的方式,方便开发。
- clientWidth 获取内容宽与左右padding之和
- clientHeight 获取内容高与上下padding之和
- offsetWidth 获取内容宽与左右padding与左右border宽度之和(不包含滚动条)
- offsetHeight 获取内容高与上下padding与上下border宽度之和(不包含滚动条)
- clientLeft 获取元素左边框宽度
- clientTop 获取元素上边框高度
使用方式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 200px;
margin: 0 auto;
background-color: tomato;
border: 10px solid red;
padding: 20px;
}
</style>
</head>
<body>
<div id="box" class="box">内容内容</div>
<script>
var box = document.getElementById("box");
console.log(box.clientWidth); // 20px + 100px +20px = 140px
console.log(box.clientHeight); // 20px + 200px + 20px = 240px
console.log(box.offsetWidth); // 10px + 20px + 100px + 20px + 10px = 160px
console.log(box.offsetHeight); // 10px + 20px + 200px + 20px + 10px = 260px
console.log(box.clientLeft); // 10px
console.log(box.clientTop); // 10px
</script>
</body>
</html>
快捷位置与距离
有时候我们需要获取自身元素到某个元素位置的距离,可以使用以下快捷方式:
- offsetParent 定位父元素。指的是自身元素相对于的定位元素,如果一个元素自身没有定位,也会找到祖先元素中的第一个拥有定位的元素,如果都没有,就是body
- offsetLeft 自身元素左边框外到定位父元素的左边框内 (IE8 到定位父元素的左边框外)
- offsetTop 自身元素上边框外到定位父元素的上边框内 (IE8 到定位父元素的上边框外)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
position: relative;
width: 500px;
height: 500px;
margin: 100px auto;
background-color: tomato;
border: 10px solid red;
}
.box1{
position: absolute;
width: 200px;
height: 200px;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
background-color: yellow;
border: 10px solid green;
}
</style>
</head>
<body>
<div id="box" class="box">
box
<div id="box1" class="box1">box1</div>
</div>
<script>
var box = document.getElementById("box");
var box1 = document.getElementById("box1");
console.log(box1.offsetParent.nodeName); // 获取定位父元素名称 DIV
console.log(box1.offsetLeft); // 140px
console.log(box1.offsetTop); // 140px
</script>
</body>
</html>
写一个函数,让函数接收一个元素作为参数,返回该元素到页面两边的距离
要注意offsetLeft和offsetTop在IE8中存在兼容问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
position: relative;
width: 500px;
height: 500px;
margin: 100px auto;
background-color: tomato;
border: 10px solid red;
}
.box1{
position: absolute;
width: 200px;
height: 200px;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
background-color: yellow;
border: 10px solid green;
}
</style>
</head>
<body>
<div id="box" class="box">
box
<div id="box1" class="box1">box1</div>
</div>
<script>
// 写一个函数,让函数接收一个元素作为参数,返回该元素到页面两边的距离
function offset(dom){
var obj = {
left: dom.offsetLeft,
top: dom.offsetTop
}
// 定义一个变量,指示是否是IE8
var isIE8 = window.navigator.userAgent.indexOf("MSIE 8") != -1;
// 循环开始
while(dom != document.body){
// 将dom变量指向上一层元素
dom = dom.offsetParent;
// 让obj累计上一层的元素的距离
// 如果是IE8,则执行
if(isIE8){
obj.left += dom.offsetLeft;
obj.top += dom.offsetTop;
}else{
// 如果不是IE8,则执行
obj.left += dom.clientLeft + dom.offsetLeft;
obj.top += dom.clientTop + dom.offsetTop;
}
}
// 返回结果
return obj;
}
// 传递box1时,要获取的是box1这个元素到页面两边的距离
var obj = offset(box1);
console.log("box1_left:"+obj.left);
console.log("box1_top:"+obj.top);
// 传递box时,要获取的是box这个元素到页面两边的距离
var obj1 = offset(box);
console.log("box_left:"+obj1.left);
console.log("box_top:"+obj1.top);
</script>
</body>
</html>
通过案例了解scrollTop和scroll事件
案例1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.header{
width: 100%;
height: 200px;
background-color: cadetblue;
}
ul, ol, nav li{
list-style: none;
}
.nav{
float: right;
width: 100px;
height: auto;
background-color: chocolate;
text-align: center;
position: sticky;
top: 0;
}
.nav li{
height: 40px;
line-height: 40px;
cursor: pointer;
}
.wrapper{
width: 100%;
height: auto;
}
.wrapper li{
height: 600px;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<div id="header" class="header"></div>
<ul id="nav" class="nav">
<li><a>1板块</a></li>
<li><a>3板块</a></li>
<li><a>2板块</a></li>
<li><a>4板块</a></li>
<li><a>5板块</a></li>
<li><a>6板块</a></li>
<li><a>7板块</a></li>
<li><a>8板块</a></li>
<li><a>9板块</a></li>
<li><a>10板块</a></li>
<li><a>11板块</a></li>
<li><a>12板块</a></li>
</ul>
<ul id="wrapper" class="wrapper">
<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>
<li>11板块</li>
<li>12板块</li>
</ul>
<script>
// 获取nav所有a标签,放到数组里面,因为通过querySelectorAll方式获取到的是类数组,需要将类数组转为数组
let arrs = [].slice.call(document.querySelectorAll("a"));
// 遍历arrs数组
arrs.forEach(function(value, index, self){
// arrs里面任意一个a标签被点击
value.onclick = function(){
// 滚动条滚动到对应的位置
document.documentElement.scrollTop = 200 + 602*index;
document.body.scrollTop = 200 + 602*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">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.header{
width: 100%;
height: 200px;
background-color: cadetblue;
}
ul, ol, nav li{
list-style: none;
}
.nav{
float: right;
width: 100px;
height: auto;
background-color: chocolate;
text-align: center;
position: sticky;
top: 0;
}
.nav li{
height: 40px;
line-height: 40px;
cursor: pointer;
}
.wrapper{
width: 100%;
height: auto;
}
.wrapper li{
height: 600px;
border: 1px solid #ccc;
}
.backTop{
position: fixed;
right: 0;
bottom: 30px;
width: 100px;
height: 40px;
line-height: 40px;
cursor: pointer;
text-align: center;
background-color: darkgreen;
border: none;
color: #fff;
display: none;
}
</style>
</head>
<body>
<div id="header" class="header"></div>
<ul id="nav" class="nav">
<li><a>1板块</a></li>
<li><a>3板块</a></li>
<li><a>2板块</a></li>
<li><a>4板块</a></li>
<li><a>5板块</a></li>
<li><a>6板块</a></li>
<li><a>7板块</a></li>
<li><a>8板块</a></li>
<li><a>9板块</a></li>
<li><a>10板块</a></li>
<li><a>11板块</a></li>
<li><a>12板块</a></li>
</ul>
<ul id="wrapper" class="wrapper">
<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>
<li>11板块</li>
<li>12板块</li>
</ul>
<button id="backTop" class="backTop">
回到顶部
</button>
<script>
// 获取元素
let vackTop = document.getElementById("backTop");
// 获取nav所有a标签,放到数组里面,因为通过querySelectorAll方式获取到的是类数组,需要将类数组转为数组
let arrs = [].slice.call(document.querySelectorAll("a"));
// 遍历arrs数组
arrs.forEach(function(value, index, self){
// arrs里面任意一个a标签被点击
value.onclick = function(){
// 滚动条滚动到对应的位置
document.documentElement.scrollTop = 200 + 602*index;
document.body.scrollTop = 200 + 602*index;
}
})
// 获取页面高度
let pageHeight = document.body.clientHeight;
// 获取视口高度
let viewHeight = document.documentElement.clientHeight;
// 延时器名
let timer = null;
// 页面滚动事件
document.onscroll = function(){
console.log(1);
// 获取页面滚动值
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
// 判断是否即将滚动到页面底部
if(pageHeight - scrollTop - viewHeight < 300){
console.log(2)
clearTimeout(timer);
// 设置延时器器
timer = setTimeout(function(){
backTop.style.display = "block";
},500);
}else{
backTop.style.display = "none";
}
}
// backTop点击事件
backTop.onclick = function(){
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
}
</script>
</body>
</html>