详解JavaScript三大家族

妹子.jpg

offset、scroll还有client这三个属性总是让人头疼,好不容易记下没过多久就又忘了。。。这次好好总结一下(@_@;)~

为了让文章更显而易见一点,我们先定义段代码:

  <div class="box">
      <div class="box1"></div>
  </div>
  <div class="box2"></div>

如上所示,我们有三个盒子。
然后再来定义样式:

        .box {
            width: 300px;
            height: 300px;
            margin: 0 auto;
            padding: 50px 100px;
            background-color: orange;
            position: relative;
        }
        .box1 {
            width: 100px;
            height: 100px;
            border: 10px solid transparent;
            background-color: green;
        }
        .box2 {
            width: 100px;
            height: 100px;
            background-color: blue;
            position: absolute;
            left: 250px;
            top: 200px;
        }

这样,我们就可以得到如下的页面:


template.png

其中橙色的box是最外一层的大盒子,包含着绿色的box1,蓝色的box2和box在同一级。
好了,有了上面这个简单(丑陋)的页面,我们就可以好好的来研究一下了~


offset系列

打印出上面每个盒子对应offset系列的属性值:


offsetLog.png

由上图我们可以看出,offsetWidth返回的是元素包含padding和border的宽度,offsetHeight一样,只不过返回的是高度而已,但offsetLeftoffsetTap返回的值不太明显,但其实仔细看,会发现他们返回的都是相对于offsetParent元素的值,当offsetParent为body时,返回相对body的距离,offsetParent为box时,返回相对于box的距离。

我们来查看一下offset系列属性的定义:

  • offsetWidth: 只读属性,返回一个元素的布局宽度,包括边框(border)、内边距(padding)、内容(content)和竖直滚动条的宽度(如果有的话)。
  • offsetHeight:只读属性,返回一个元素的像素高度,包括边框(border)、内边距(padding)、内容(content)和竖直滚动条的宽度(如果有的话)。
  • offsetLeft:只读属性,返回元素相对于offsetParent元素的左边界对应的像素值。
  • offsetTop: 只读属性,返回元素相对于offsetParent元素的顶部距离。
  • offsetParent:只读属性,返回一个指向最近的包含该元素的定位元素。

这样就很清楚了,不过怎么知道offsetWidth会包含滚动条的宽度?
其实很简单,在box的样式里加一行代码:

.box {
  overflow: hidden;
}

这样就好了,最后打印的结果并没有变化。

对了, 还有offsetParent属性,如果没有定位的父元素怎么办呢?

由上面的例子可以看出,如果没有定位的父元素,则默认是body元素。

其实按照MDN的说法,如果没有定位的父元素,则offsetParent为最近的table、table-cell或根元素(body元素)。

最后,要注意的是:

offsetTop和offsetLeft在计算时不考虑父元素的边框


scroll系列

我们还是先打印出scroll系列属性的值来看看~


scrollLog.png

\

乍一看好像和offset没啥区别。。。不过仔细看看,会发现scrollWidthscrollHeight不会计算元素的边框(border)。

但是scrollTopscrollLeft一直是0是什么鬼呢( ఠൠఠ )ノ?

想不出原因的话,我们让元素滚动一下试试~(毕竟scroll,scroll,一直在叫我们滚嘛。。。( ╯□╰ )囧)
给之前的样式表添加如下样式:

        .box {
            overflow: scroll;
        }
        .box1 {
            height: 1000px;
        }

就是给box加了个滚动条,把box1的高度改为了1000px。

现在我们的图就是这样了:

image.png

为了看清楚scrollTop的值,为box元素添加事件监听器,让box在滚动的时候打印一下scrollTop~

box.addEventListener("scroll", function(e) {
    console.log("scrollTop", this.scrollTop);
});

可以得到如下的结果:


image.png

当我从上向下移动滚动条的时候,scrollTop的值在逐渐增大。

这下明白了,原来scrollTop获得的是元素滚动的距离。换句话说,也就也是竖直滚动条到元素顶部的距离。

scrollLeft类似,就不再说了。

做个小总结:

  • scrollWidth: 只读属性。一个元素内容宽度的度量,包括由于溢出导致的视图中不可见内容(不包括滚动条和border)。
  • scrollHeight: 只读属性。一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容(不包括滚动条和border)。
  • scrollTop: 读取元素滚动条到元素顶部的距离(不包括滚动条和border)
  • scrollLeft: 读取元素滚动条到元素左边的距离(不包括滚动条和border)

这里补充一下:

offset系列属性是包含滚动条的。


client系列

直接看结果:


image.png

可以看到,clientHeight和clientWidth和offset差不多,只不过不包含边框的值(也不包含滚动条)。

而clientTop和clientLeft则返回了元素的边框宽度。

MDN的描述如下:

  • clientHeight: 只读属性,对于没有定义CSS或者内联布局盒子的元素为0,同时它是元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距。
  • clientWidth: 元素的内部宽度,以像素计。该属性包括内边距,但不包括垂直滚动条(如果有)、边框和外边距。
  • clientTop: 只读元素,一个元素顶部边框的宽度(以像素表示)。不包括顶部外边距或内边距。
  • clientLeft: 表示一个元素的左边框的宽度,以像素表示。

要注意的是:

如果元素的文本方向是从右向左(RTL, right-to-left),并且由于内容溢出导致左边出现了一个垂直滚动条,则该属性包括滚动条的宽度。


最后,我们拓展一点内容

  1. 关于event事件的几个属性
    • clientXclientY: 相对于浏览器(可视区左上角0,0)的坐标,不包含滚动区域。
    • screenXscreenY: 相对于设备屏幕左上角(0,0)的坐标。
    • offsetXoffsetY: 相对于事件源左上角(0,0)的坐标,不包括border。
    • pageXpageY: 相对于整个网页左上角(0,0)的坐标,包含滚动区域。
  2. window相关宽高属性
    • window.outerHeight:获取整个浏览器窗口的高度(单位:像素),包括侧边栏(如果存在)、窗口镶边(window chrome)和窗口调正边框。包含调试窗及浏览器边框
    • window.outerWidtht:表示整个浏览器窗口的宽度,包括侧边栏(如果存在)、窗口镶边(window chrome)和调正窗口大小的边框。包含调试窗及浏览器边框
    • window.innerHeight:浏览器窗口的视口(viewport)高度(以像素为单位),如果存在水平滚动条,则包括它。不包含调试窗及浏览器边框
    • window.innerWidth:浏览器视口(viewport)宽度(单位:像素),如果存在垂直滚动条则包括它。不包含调试窗及浏览器边框
    • window.screen.width:声明了显示当前浏览器的屏幕的宽度,以像素计
    • *window.screen.height:声明了显示当前浏览器的屏幕的高度,以像素计
    • *window.screen.availHeight:声明了显示浏览器的屏幕的可用高度,以像素计。除去我们底部任务栏外的屏幕高度
    • *window.screen.availWidth:声明了显示浏览器的屏幕的可用宽度,以像素计
    • *window.screenLeft:只读属性,返回窗口的左上角在屏幕上的x坐标。在Firefox等浏览器中使用的是screenX属性。
    • *window.screenTop:只读属性,返回窗口的左上角在屏幕上的y坐标。在Firefox等浏览器中使用的是screenY属性。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容