块块的宽高及偏移位
复习一下的 background 模块: 盒模型刨去 margin, border, padding 后剩的就是 content
花式获取元素宽高
- style
- getComputedStyle (这个好)
- offsetWidth, offsetHeight
currentStyle
-
style (行内样式)
通过style属性获取宽高
- 获取的宽高只是 content 的宽高, 即不包括 padding 和 border (当然更没有 margin)
- 只能获取通过行内样式设置的宽高
- 可以获取也可以设置
-
getComputedStyle (重要)
- 获取的宽高不包括 边框和内边距
- 即可以获取行内设置的宽高也可以获取 CSS 设置的宽高
- 只支持获取, 不支持设置
- 上古浏览器用不了这个
-
offsetWidth, offsetHeight
- 获取的宽高包含 ==border+padding+content==
- 即可以获取行内设置的宽高也可以获取 CSS 设置的宽高
- 只支持获取, 不支持设置
-
currentStyle(上古, 废弃)- 获取的宽高不包括 边框和内边距
- 即可以获取行内设置的宽高也可以获取 CSS 设置的宽高
- 只支持获取, 不支持设置
- 只支持 IE9 以下浏览器
- 所以
currentStyle是 getComputed 的上古版本
拿元素宽高四种方式的辨析
宽高是哪部分的宽高
- getComputedStyle/currentStyle/style 获取的宽高只是 content 的宽高, 不包括 边框和内边距
- offsetWidth/offsetHeight (独特) 获取的宽高包括 边框和内边距
样式是哪里的样式
- getComputedStyle/currentStyle/offsetXXX 即可以获取行内,也可以获取外链和内联样式, 只支持获取, 不支持设置
- style 只能获取行内样式, 可以获取, 也可以设置
元素不同的偏移位们
偏移位三个族
- offsetLeft, offsetTop
- clientLeft, clientTop
- scrollTop (也有 scrollLeft, 但是比较少用)
offsetLeft, offsetTop
简单来说, offset 族都是相对于最近层级的定位元素的
- offsetLeft, offsetTop
- 获取元素到第一个定位祖先元素之间的偏移位
- 如果没有祖先元素是定位的, 获取到相对于 body 的偏移位
- offsetParent
- 获取元素的第一个定位祖先元素
- 如果没有祖先元素是定位的, 那么就是获取到的就是 body
<!-- offsetLeft, offsetTop -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JavaScript-获取元素位置-offsetLeft, offsetTop</title>
<style>
* {
margin: 0;
padding: 0;
}
.father {
width: 200px;
height: 200px;
margin-top: 100px;
margin-left: 100px;
background: blue;
overflow: hidden;
position: relative;
}
.son {
width: 100px;
height: 100px;
margin-top: 100px;
margin-left: 100px;
background: red;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
/*
获取元素到第一个定位祖先元素之间的偏移位
如果没有祖先元素是定位的, 那么就是获取到body的偏移位
*/
let oSDiv = document.querySelector(".son");
oSDiv.onclick = function () {
console.log(oSDiv.offsetLeft); // 100
console.log(oSDiv.offsetTop); // 100
};
</script>
</body>
</html>
<!-- offsetParent -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JavaScript-offsetParent</title>
<style>
* {
margin: 0;
padding: 0;
}
.grand-father {
width: 300px;
height: 300px;
margin-top: 100px;
margin-left: 100px;
background: deeppink;
overflow: hidden;
position: relative;
}
.father {
width: 200px;
height: 200px;
margin-top: 100px;
margin-left: 100px;
background: blue;
overflow: hidden;
position: relative;
}
.son {
width: 100px;
height: 100px;
margin-top: 100px;
margin-left: 100px;
background: red;
}
</style>
</head>
<body>
<div class="grand-father">
<div class="father">
<div class="son"></div>
</div>
</div>
<script>
let oSDiv = document.querySelector(".son");
oSDiv.onclick = function () {
console.log(oSDiv.offsetParent); // <div class="father">…</div>
};
</script>
</body>
</html>
clientLeft, clientTop
- clientWidth, clientHeight
- clientWidth = content+padding
- clientHeight = content+padding
- clientLeft, clientTop
- 左边框和顶部边框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JavaScript-client族</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 150px;
height: 150px;
padding: 100px;
border: 50px solid #000;
background: red;
background-clip: content-box;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
let oDiv = document.querySelector("div");
console.log(oDiv.clientWidth); // 350
console.log(oDiv.clientHeight); // 350
console.log(oDiv.clientLeft); // 50
console.log(oDiv.clientTop); // 50
</script>
</body>
</html>
scrollTop
scrollWidth, scrollTop
- 内容没有超出元素范围时
- scrollWidth = content+padding == clientWidth
- scrollHeight = content+padding == clientHeight
- 内容超出元素范围时 (试过的)
- 内容相对于初始位置的位移, 一旦开始滚动就会有输出
- 小意外: 这里第二个页面滚动条出现后宽度缩水了! 从 200 缩水到了 183.
<!-- 内容没有超出块块的时候 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JavaScript-scroll属性</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 100px;
height: 100px;
padding: 50px;
border: 50px solid #000;
background: red;
background-clip: content-box;
color: deepskyblue;
overflow: auto;
}
</style>
</head>
<body>
<div id="box">
我是内容<br />
我是内容<br />
</div>
<script>
let oDiv = document.querySelector("div");
console.log(oDiv.scrollWidth); // 200
console.log(oDiv.scrollHeight); // 200
oDiv.onscroll = function () { // 没有滚动条
console.log(oDiv.scrollTop);
};
</script>
</body>
</html>
<!-- 内容超出块块的时候 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JavaScript-scroll属性</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 100px;
height: 100px;
padding: 50px;
border: 50px solid #000;
background: red;
background-clip: content-box;
color: deepskyblue;
overflow: auto;
}
</style>
</head>
<body>
<div id="box">
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
我是内容<br />
</div>
<script>
let oDiv = document.querySelector("div");
console.log(oDiv.scrollWidth); // 183
console.log(oDiv.scrollHeight); // 425
oDiv.onscroll = function () { // 一旦开始滚动, 就开始输出
console.log(oDiv.scrollTop);
};
</script>
</body>
</html>
可视区域的宽高
- window.innerWidth, window.innerHeight (现代, 只在 IE9 及以上浏览器可用)
document.documentElement.clientWidth, document.documentElement.clientHeight(上古标准模式)document.body.clientWidth, document.body.clientHeight(上古怪异模式):warning:
注意点:
- 浏览器在渲染网页的时候有两种模式"标准模式"/"混杂(怪异)模式"
- 默认情况下都是以标准模式来进行渲染的 (CSS1Compat)
- 如果网页没有书写文档声明, 那么就会按照"混杂(怪异)模式"来进行渲染 的(BackCompat)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JavaScript-获取网页宽高</title>
</head>
<body>
<script>
let { width, height } = getScreen();
console.log(width);
console.log(height);
function getScreen() {
var width, height;
if (window.innerWidth) {
width = window.innerWidth;
height = window.innerHeight;
} else if (document.compatMode === "BackCompat") {
console.log(document.compatMode);// BackCompat
width = document.body.clientWidth;
height = document.body.clientHeight;
} else {
console.log(document.compatMode);// CSS1Compat
width = document.documentElement.clientWidth;
height = document.documentElement.clientHeight;
}
return {
width: width,
height: height,
};
}
</script>
</body>
</html>
-
关于 document 对象和 window 对象
<html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>document 和 window</title> <script> console.log(window); console.log(document); </script> </head> <body> 总之 window 是个大而全的对象, document 就是比较纯粹的 html 文档 </body> </html><!-- 文档声明加和不加行为是一样的, 应该是浏览器优化过了 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>document.documentElement 和 window</title> <script> console.log(document); // 比 document.documentElement 多了个文档声明 (如果有的话) console.log(document.documentElement); // 和 line13 打印的数字相同 console.log(document.documentElement.clientWidth); // 和 line14 打印的数字相同 console.log(document.documentElement.clientHeight); console.log(window.innerWidth); console.log(window.innerHeight); // console.log(document.body.clientWidth); 这俩在现代浏览器里会报错 // console.log(document.body.clientHeight); </script> </head> <body></body> </html>