美文网首页
overflow属性引发的浏览器滚动条血案

overflow属性引发的浏览器滚动条血案

作者: 简森w | 来源:发表于2018-05-04 12:43 被阅读0次

案发现场

今天给后台的表格组件替换为一个前同事写的表格组件,替换完发现除了滚动条不能用鼠标滚动以外,其他都没什么大问题。我是一个跟任何东西都可以较劲的人,我不信一个小小的滚动条还能奈我何?于是就发生了这个血案。从看源码,到问前同事,足足浪费了我一个下午来找问题,深深地感到自己的能力是如此的不足。

案发详情

滚动条归属的问题。

我们都知道,如何页面超过了浏览器窗口的大小,浏览器会自动生成一个滚动条。这个滚动条是属于谁的?是属于html元素还是body元素的?

都不是!!

当一个子元素超过了其父元素的限定高度并且在父元素设置了overflow:auto或者overflow:scroll父元素容器就会产生一个滚动条,这个滚动条毫无疑问是归属于父元素的。直接看demo01,以下是demo01的主要代码:

<div class="parent">
    parent
    <div class="child">
        child
    </div>
</div>
body{
    margin:0;
}
.parent{
    height:400px;
    border:1px solid #ddd;
    overflow:auto;
}

.child{
    height:800px;
    background-color:#eee;
}

可以看到,child撑开了parent的高度,于是parent生成了滚动条,滚动条属于parent,这个是没有争议的。

如何判断滚动条的归属呢?

一种直观的方法:可以通过控制台的Element面板,把鼠标hover在parent元素上,可以看到滚动条是在元素内部的。(在Mac下,滚动条的表现形式不太一样,只有滚动的时候才会出现滚动条,没有滚动时自动隐藏)

另一种方法是可以通过对元素添加scroll监听事件来判断。

如果是body下的直接子元素的高度超过了body的限定高度,并且给body增加overflow :auto,这时生成的滚动条是属于谁的?看一下例子demo02,以下是主要代码:

<div class="child">
    Child
</div>
html, body{
    height:100%;
}
body{
    margin:0;
    overflow:auto;
}
.child{
    height:1000px;
    background-color:#eee;
}

咦,好像滚动条并不属于body元素??确实不属于body,也不属于html。Mac下按照上面第一种方法观察,滚动条好像是属于html元素的,但其实不然,可以通过给元素添加scroll事件的监听就可以发现,滚动的时候并不会触发html元素或者body元素的scroll事件。

//监听window窗口的滚动事件
window.addEventListener('scroll', (e) => {
    console.log('window');
})
//监听document对象的滚动事件
document.addEventListener('scroll', (e) => {
    console.log('document');
})
//监听html元素的滚动事件
document.documentElement.addEventListener('scroll', (e) => {
    console.log('html');
})
//监听body元素的滚动事件
document.body.addEventListener('scroll', (e) => {
    console.log('body');
})

上面的四个监听器,滚动的时候只有前两个才会被触发,所以证明滚动条是属于document对象的。

为什么window也能监听到scroll事件呢?这是因为事件冒泡

当html元素也添加overflow:auto时,滚动条会是谁的呢?看例子demo03

这时,滚动条貌似是属于body的?是的没错,就是属于body的,用监听器来监听一下滚动事件,只会触发document.body的监听器,而不会触发windowdocument的。

为什么会这样?应该不仅只有我一个人才发现滚动条这个坑的吧?TAT

先来回顾一下overflow有哪些值:

/* 默认值。内容不会被修剪,会呈现在元素框之外*/
overflow: visible;

/* 内容会被修剪,并且其余内容不可见 */
overflow: hidden;

/* 内容会被修剪,浏览器会显示滚动条以便查看其余内容 */
overflow: scroll;

/* 由浏览器定夺,如果内容被修剪,就会显示滚动条 */
overflow: auto;

/* 规定从父元素继承overflow属性的值 */
overflow: inherit;

于是得出结论(也可以说个人猜测,因为不一定正确):

htmlbody仅有一个元素会产生滚动条时,这个滚动条会默认归属于document

htmlbody元素的overflow属性都是默认值auto时,因为body高度可能超过html的高度,这时就会产生一个滚动条,这个滚动条属于document的,所以如果body再产生一个滚动条,就只能是属于body自己的了。

鼠标滚轮事件

页面出现滚动条时,我们可以用鼠标滚轮来对页面进行纵向滚动,那是否可以组织这个滚动行为呢?

肯定是可以的。e.preventDefault()就是阻止事件的默认行为,在mousewheel事件监听里加上这句,就能阻止鼠标滚轮触发滚动事件了。

戳栗子demo04

因为这个,让我在组件源码里折腾了好一会,当然不是不知道e.preventDefault(),是忽略了它的作用。


因为工作忙,这篇文章前后写了好久,当时的一些思路灵感都已经消逝了,写不下去了,先到这为止吧,之后有想起什么遗漏的再补上。

相关文章

  • overflow属性引发的浏览器滚动条血案

    案发现场 今天给后台的表格组件替换为一个前同事写的表格组件,替换完发现除了滚动条不能用鼠标滚动以外,其他都没什么大...

  • overflow滚动条

    overflow一共有以下属性overflow:hidden 溢出隐藏,不显示,也无滚动条overflow:scr...

  • css溢出显示滚动条

    文本或者内容溢出滚动条显示: a、横纵都出滚动条:css添加属性{overflow:auto;}b、横向滚动条:c...

  • CSS overflow 属性

    实例设置overflow属性: 浏览器支持所有主流浏览器都支持overflow属性。注释:任何的版本的Intern...

  • 溢出处理

    overflow 属性:hidden 溢出隐藏auto 溢出部分出现滚动条scroll 一直出现滚动条visibl...

  • overflow与滚动条

    1.滚动条出现条件 overflow:auto/scroll / 等元素自带 内容尺寸超出容器 2.浏览器滚动条 ...

  • 深入理解之overflow

    一、overflow的属性 visible 默认值hidden 溢出隐藏scroll 显示滚动条auto 溢出滚动...

  • scroll系列 相关属性

    元素内容溢出 && 设置了元素的overflow属性,产生滚动条或超出内容被隐藏 实际上,不管是滚动条还是超出...

  • 第三天:让简历有点色彩

    将网页在浏览器中一屏显示,不出现滚动条 body{width:100%;height:100%;overflow:...

  • CSS overflow 属性

    overflow 属性规定如何处理如何处理不符合元素框的内容。 大多数主流浏览器都支持 overflow 属性。 ...

网友评论

      本文标题:overflow属性引发的浏览器滚动条血案

      本文链接:https://www.haomeiwen.com/subject/vqddrftx.html