clientLeft、clientHeight、clientWidth、clientHeight
clientWidth
、clientHeight
元素内部宽度和高度, clientLeft
、clientTop
获取元素内边距边框到边框的距离.
大概如下图所示:
clientWidth
属性表示元素的内部宽度,以像素计。该属性包括内边距,但不包括垂直滚动条(如果有)、边框和外边距。
如上图所示, 计算方式为, 分为如下两种:
- 存在垂直滚动条
content width + padding - scollbarWidth
- 不存在滚动条
content width + padding
clientHeight
属性表示元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距。
如上图所示, 计算方式为如下两种:
- 存在水平滚动条
content height + padding - scollbarWidth
- 不存在滚动条
content height + padding
clientLeft
表示一个元素的左边框的宽度.
计算方式为如下两种情况:
- 如果文字方向从右往左(默认从左往右,通过设置 direction: rtl;)进行排列,且存在垂直滚动条的情况下
border width + scollbar width
- 默认情况下
border width
注意:
如果当前元素是行内元素(inline)时, clientLeft将返回 0;
clientTop
表示一个元素的上边框的宽度.
把基本的情况介绍完了看看具体实例,代码如下:
<style>
.box {
width: 200px;
height: 200px;
overflow: hiddle;
margin: 10px;
padding: 10px;
border: 5px solid black;
background-color: #ccc;
direction: rtl;
}
</style>
<div class="box" id="box">
</div>
<script>
var ele = document.querySelector("#box");
var clientWidth = ele.clientWidth;
var clientHeight = ele.clientHeight;
var clientLeft = ele.clientLeft;
var clientTop = ele.clientTop;
console.log(clientWidth, clientHeight, clientLeft, clientTop);
// 220 , 220, 5, 5
</script>
这是不存在水平和垂直,以及文字按照默认情况下排列.
下面我将对上面实例进行如下修改:
- 给元素
.box
添加overflow:scroll
让它显示滚动条, 再来看看每个值:
<style>
.box {
...
overflow: scroll;
}
</style>
<script>
console.log(clientWidth, clientHeight, clientLeft, clientTop);
// 203, 203, 5, 5
</script>
如下图所示:
从输出答应结果来看, clientWidth 、clientHeight 变小了,也就是说不包含其滚动条.
- 改变容器文字输出方向,看看 clientLeft 值会不会像之前说的会加上滚动条的width ?
<style>
.box {
...
overflow: scroll;
direction: rtl;
}
</style>
<script>
console.log(clientWidth, clientHeight, clientLeft, clientTop);
// 203, 203, 22, 5
</script>
如下图所示:
从打印结果来看, 改变文字方向(rtl)并且存在处置滚动条情况下:clientLeft = scrollbarWidth + borderLeftWidth
使用场景
计算滚动条宽度
默认情况下(没有滚动条情况下)
clientWidth = content width + paddingLeftWidth + paddingRightWidth;
对上面示例来说 clientWidth = 200 + 10 + 10;
有滚动条情况下:
clientWidth = (content width + paddingLeftWidth + paddingRightWidth) - scrollbarWidth
可以推断出滚动条计算方式:
scrollbarWidth = (content width + paddingLeftWidth + paddingRightWidth) - clientWidth;
clientWidth
已知, 从上面公式来看只要知道内容区域大小和左右padding值即可
var ele = document.querySelector("#box");
var computedStyle = window.getComputedStyle(ele);
var offsetWidth = ele.offsetWidth; // content widht + padding width + border width (包含滚动条)
var ceil = function(v){
return Math.ceil(parseFloat(v))
}
var maxClientWidth = offsetWidth
- ceil(computedStyle.borderLeftWidth)
- ceil(computedStyle.borderRightWidth); // ClientWidth 最大值(理想情况下, 也就是不存在滚动条)
var scrollbarWidth = maxClientWidth // 滚动条大小
- ceil(ele.clientWidth);
console.log(scrollbarWidth); // 17
这样就计算出滚动条的 width
, 高度同理可得.
上面因为使用 getComputedStyle
只能兼容到 IE9+、Chrome、Firefox、Safari 等 , 需要兼容IE8以及以下版本,可以作下兼容处理:
// 这里如果IE8以下则需要改为 getElementById
var selector = function (selectorName) {
if (!selectorName && !(typeof selectorName === "string")) { return {} };
var prefix = /^#/;
if (document.querySelector) {
selectorName = prefix.test(selectorName) ? selectorName.substr(1) : selectorName;
return document.querySelector(selectorName);
} else if(document.getElementById) {
selectorName = prefix.test(selectorName) ? selectorName : "#" + selectorName;
return document.getElementById(selectorName);
}
}
var selector = selector("box");
var computedStyle = window.getComputedStyle === undefined ? ele.currentStyle : window.getComputedStyle(ele);
var offsetWidth = ele.offsetWidth; // content widht + padding width + border width (包含滚动条)
var ceil = function (v) {
return Math.ceil(parseFloat(v))
}
var maxClientWidth = offsetWidth
- ceil(computedStyle.borderLeftWidth)
- ceil(computedStyle.borderRightWidth); // ClientWidth 最大值(理想情况下, 也就是不存在滚动条)
var scrollbarWidth = maxClientWidth // 滚动条大小
- ceil(ele.clientWidth);
console.log(scrollbarWidth); // 17
元素内部实际可用区域
可用区域其实就是内容可以排放的空间, 其可见区域宽度其实就是 clientWidth - paddingLeftWidth - paddingRightWidth 的值.
比求滚动条宽度相对简单点, 只需要知道左右内边距的大小即可.
var selector = function (selectorName) {
if (!selectorName && !(typeof selectorName === "string")) { return {} };
var prefix = /^#/;
if (document.querySelector) {
selectorName = prefix.test(selectorName) ? selectorName.substr(1) : selectorName;
return document.querySelector(selectorName);
} else if(document.getElementById) {
selectorName = prefix.test(selectorName) ? selectorName : "#" + selectorName;
return document.getElementById(selectorName);
}
}
var selector = selector("box");
var computedStyle = window.getComputedStyle === undefined ? ele.currentStyle : window.getComputedStyle(ele);
var ceil = function (v) {
return Math.ceil(parseFloat(v))
}
console.log(ele.clientWidth - ceil(computedStyle.paddingLeft) - ceil(computedStyle.paddingRight));
上面计算方式没有什么固定,仅供参考. 更好计算方式也可以推荐下. ~ 比如通过 getBoundingClientRect()