判断是否有滚动条的需求在弹窗插件中用得较多,因为弹窗大多会添加
overflow: hidden属性,如果页面超过一屏的话,添加这个属性之后页面会有晃动。
为了增强用户体验,通过判断是否有滚动条而添加
margin-left属性以抵消overflow: hidden之后的滚动条位置。
// 判断竖向滚动条
element.scrollHeight > element.clientHeight;
// 判断横向滚动条
element.scrollWidth > element.clientWidth;
特殊情况
当元素指定了overflow: hidden是,是不会出现滚动条的,所以需要对元素是否应用了overflow: hidden进行判断。
// 封装函数
function hasScrolled(ele, dir = "vertical"){
// 判断的方向是否设置了overflow: hidden
let style = window.getComputedStyle(ele);
if( (dir == "vertical" && style.overflowY == "hidden")
||
(dir == "horizontal" && style.overflowX == "hidden")
)return false;
// 在判断完overflow不为hidden后,再通过两个属性来判断。
if(dir == "vertical"){
return (ele.scrollHeight > ele.clientHeight);
}else{
return (ele.scrollWidth > ele.clientWidth);
};
};
但是,以上的方法不严谨,当容器产生外边距合并的时候,也是ele.scrollWidth > ele.clientWidth。
<div class="box">
<h1>子元素内部内容</h1>
</div>
<script>
let box = document.querySelector(".box");
console.log("scrollHeight: " + box.scrollHeight) // scrollHeight: 63
console.log("clientHeight: " + box.clientHeight) // clientHeight: 42
console.log("是否有滚动条:", box.scrollHeight > box.clientHeight) // 是否有滚动条: true
</script>
// 做好的做法应该是:
function hasScrolled(ele, dir = "vertical"){
let eleScroll = dir == "vertical" ? "scrollTop" : "scrollLeft";
let result = !!ele[eleScroll]; // 判断scroll数值是否为0,还是其他值
// 如果是其他数值(非0)这表示有滚动条
// 如果是0,则尝试移动一下滚动条,判断是否能够移动
if(!result){
ele[eleScroll] = 1; // 尝试移动滚动条
result = !!ele[eleScroll]; // 再次确认数值
ele[eleScroll] = 0; // 恢复原位
};
return result; // 得出结果
};
计算滚动条宽度的方法
因为移动端浏览器的滚动条都是不占据页面宽度的透明样式,所以为了进一步增强用户体验,我们还需要计算滚动条的宽度,根据情况添加合理的
margin-left值
// 计算滚动条宽度的方法:新建一个带有滚动条的DIV元素,再计算该元素offsetWidth和clientWidth的差值。
function getScrollbarWidth() {
var scrollDiv = document.createElement("div");
scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
document.body.appendChild(scrollDiv);
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
return scrollbarWidth;
};