今天在解决ios移动端的滚动穿透问题的时候,遇到了一个问题,就是判断一个元素是否可以滚动,把这个过程记录下来。下面以垂直滚动为例,水平滚动同理。如果觉得麻烦,可以直接查看代码。基本概念Element.scrollHeightscrollHeight是元素内容高度的度量,包括由于溢出而在视图中不可见的内容。scrollHeight的值等于当不能出现滚动条时,元素显示视图中所有内容所需的最小高度。如果没有滚动条也能完整显示元素内容,则元素的scrollHeight和clientHeight相等。MDNElement.clientHeightclientHeight指的是元素内部的高度,包括padding,但不包括margin、border和水平滚动条。clientHeight=CSSheight+CSSpadding-水平滚动条的高度(如果有的话)MDN的第一种解决方案根据以上两个定义,很容易认为可以通过比较scrollHeight和clientHeight的大小来判断一个元素是否可以滚动。这就是我一开始所做的。函数eleCanScroll(ele){返回ele.scrollHeight>ele.clientHeight;}使用之后发现这个方法的判断大部分时候是正确的,但是在某些情况下会出现偏差。偏差1检查demo子元素是否超出父元素,父元素没有设置overflow:auto偏差2检查demo子元素相对于父元素的绝对定位在上面两个demo中,虽然scrollHeight的box元素大于clientHeight,无法滚动。其实从scrollHeight的定义就可以找到原因,scrollHeight是元素内容高度的度量,包括因为溢出而在视图中不可见的内容,也就是只要子元素元素的scrollHeight在父内容框中没有完全显示出来,不管是定位还是平移偏移导致,父元素的scrollHeight必须大于clientHeight。在许多情况下,父元素无法滚动。所以,通过比较scrollHeight和clientHeight的大小来判断一个元素是否可以滚动是错误的。我看到网上有些解决方案是判断父元素的overflow属性,但是我们知道这是不对的。解决方案正确的解决方案是从scrollTop开始。Element.scrollTop元素的scrollTop值是从元素顶部到视口可见内容(顶部)的距离的度量。当一个元素的内容不产生垂直滚动条时,那么它的scrollTop值为0。MDNscrollTop可以设置为任意整数值,还要注意:如果一个元素不能滚动(例如,它没有溢出,或者元素有一个“不可滚动”的属性),scrollTop会被设置为0。根据上面scrollTop的语法,我们可以找到一个解决方案。我们可以设置元素的scrollTop=1,然后获取下一个scrollTop。如果该值变为0,则表示该元素无法滚动。代码地址functioneleCanScroll(ele){if(!eleinstanceofHTMLElement){console.log("fuckoff");返回;}如果(ele.scrollTop>0){返回真;}else{ele.scrollTop++;//如果元素不能滚动,scrollTop设置不会生效,会被设置为0consttop=ele.scrollTop;//重置滚动位置top&&(ele.scrollTop=0);返回顶部>0;}}参考文档https://developer.mozilla.org...https://developer.mozilla.org...https://developer.mozilla.org...
