html判断是否有滚动条,JS 判断元素是否可以滚动

今天在解决 ios 移动端滚动穿透的问题时遇到一个问题,就是判断元素能否滚动,把这个过程记录下来。以下以纵向滚动为例,横向滚动同理。

嫌麻烦的可以直接查看代码。

基础概念

Element.scrollHeight

scrollHeight 是一个元素内容高度的度量,包括由于溢出导致的视图中不可见的内容,scrollHeight 的值等于元素在不能出现滚动条的时候展示出视图中所有内容所需要的最小高度。

如果元素内容能在不出现滚动条的情况下全部展示,那么元素的 scrollHeight 和 clientHeight 相等。MDN

Element.clientHeight

clientHeight 是指元素内部高度,包括 padding,但不包括 margin、border 以及 横向滚动条。

clientHeight = CSS height + CSS padding - height of horizontal scrollbar (if present)MDN

第一个方案

根据上面两个定义,很容易就想到可以通过比较 scrollHeight 和 clientHeight 的大小来判断元素是否可以滚动。最开始我就是这么做的。

function eleCanScroll(ele) {

return ele.scrollHeight > ele.clientHeight;

}

使用之后发现这个方法大部分时候判断是对的,但是在一些情况下就出现的偏差。

偏差1

查看demo

子元素超出父元素,而且父元素不设置 overflow: auto

偏差2

查看demo

子元素相对父元素绝对定位

上面的两个 demo 中,虽然 box 元素的 scrollHeight 大于 clientHeight,但是并不能滚动。

其实原因从 scrollHeight 的定义中就能找到,scrollHeight 是一个元素内容高度的度量,包括由于溢出导致的视图中不可见的内容,也就是说,只要元素的子元素没有完全在父级内容框中显示出来,不管是因为定位还是 translate 偏移导致,父级元素的 scrollHeight 就一定大于 clientHeight。而这里面很多情况下父级元素都是不能滚动的。

所以通过比较 scrollHeight 和 clientHeight 的大小来判断元素是否可以滚动的方法是错误的,我看网上有的解决办法是判断父级元素的 overflow 属性,但我们知道这样也是不对的。

解决方案

正确的解决办法就要从 scrollTop 上入手了。

Element.scrollTop

一个元素的 scrollTop 值是这个元素的顶部到视口可见内容(的顶部)的距离的度量。当一个元素的内容没有产生垂直方向的滚动条,那么它的 scrollTop 值为0。MDN

scrollTop 可以被设置为任何整数值,同时注意:如果一个元素不能被滚动(例如,它没有溢出,或者这个元素有一个"non-scrollable"属性), scrollTop将被设置为0。

根据上面 scrollTop 的语法我们就能找到解决方案。我们可以设置元素的 scrollTop = 1,再获取下 scrollTop,如果值变为 0,说明该元素不可以滚动。

代码地址

function eleCanScroll(ele) {

if (!ele instanceof HTMLElement) {

console.log("fuck off");

return;

}

if (ele.scrollTop > 0) {

return true;

} else {

ele.scrollTop++;

// 元素不能滚动的话,scrollTop 设置不会生效,还会置为 0

const top = ele.scrollTop;

// 重置滚动位置

top && (ele.scrollTop = 0);

return top > 0;

}

}

参考文档

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[JS 判断元素是否可以滚动]http://www.zyiz.net/tech/detail-114698.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值