起因
说实话,撸了接近三年的前端。每次要用到innerWidth
、outerWidth
、screen.width
、vw
、clientWidth
和 getBoundingClientRect
,都很可耻地点击谷歌浏览器,然后…你懂的。才能知道我应该用那个。在此之前,我草草写了一篇极短的文章,天真地以为自己理解了,谁知不然,每次都是很熟练地…,哦不。
贴上图片,引以为戒: 说实话,至今没看懂这张图片,并且不知道为什么当初会吧这张图片放上去。手动狗头
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HjoXgJpJ-1633676828425)(006tNbRwgy1g9u1cw781ij311y0u0x68.jpg)]
在某一天,看到张鑫旭大神的文章里面写的这段话
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4rqLvVGh-1633676828427)(006tNbRwgy1g9u1i2k37hj31a207wmz7.jpg)]
如果还是大神牛逼啊!几句话就将得清楚明白了。这里少了getBoundingClientRect
、clientWidth
,所以我自己打算补充,并且以此吃透。
一个demo + 一篇文章 就可以理解 innerWidth
、outerWidth
、screen.width
、vw
附上张鑫旭大神的文章,写得非常可以有趣通俗易懂地理解 vw。视区相关单位vw, vh…简介以及可实际应用场景。是的,你没看错,人家大神2012已经开始了解vw了,并且还尝试考虑了vw的使用场景
请狠狠点击这里,张鑫旭写的demo。
理解 getBoundingClientRect, clientWidth
前提条件
由张鑫旭大神的文章 可知,“视区” 所指为浏览器内部的可视区域大小,即window.innerWidth/window.innerHeight
大小,不包含任务栏标题栏以及底部工具栏的浏览器区域大小。
从而得出 vw
, 则是 window.innerWidth
不包含任务标题栏以及底部工具栏的浏览器区域大小。也就是说整个网页内容的大小,不受其它因素的影响。
如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pr2fr1Nl-1633676828427)(lbQsBT.png)]
图片红色矩形部分,包括滚动条都属于 vw
的内容,而椭圆形的标题栏则不包括
请狠狠看这里
See the Pen [innerWidth、outerWidth、screen.width、getBoundingClientRect、clientWidth](https://codepen.io/celverbamboo/pen/povbNKN) by bamboo ([@celverbamboo](https://codepen.io/celverbamboo)) on [CodePen](https://codepen.io).不断切换 select 里面的 vw的基础值,观察 图片的 width 、 getBoundingClientRect的width即可 clientWidth宽度,如下图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sha8D5JX-1633676828429)(lb1BwT.gif)]
当为 10vw时,width : 101.9px, getBoundingClientRect: 101.890625 px, clientWidth: 102 px
当为 20vw时,width : 203.8px, getBoundingClientRect: 203.796875 px, clientWidth: 204 px
当为 30vw时,width : 305.7px, getBoundingClientRect: 305.6875 px, clientWidth: 306 px
…
由此我们可以得出以下结论:
- width 获取图片元素保留一位小数的宽度
- getBoundingClientRect 获取的元素宽度可以准确获取到小数值
- clientWidth 只能获取元素宽度的整数,则会对元素进行四舍五入的计算
同时可以看出,width以及 clientWidth是基于 getBoundingClientRect进行换算的
应用场景
既然我们知道了 width、getBoundingClientRect以及clientWidth异同和关系。下面来说说,它们在实际写项目的时候应用场景
width
看下面一张图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H7pj2xF8-1633676828430)(lb3rut.png)]
该图商品列表中,用户可以横向滚动商品。横向滚动的效果实现,需要明确知道所有商品元素的宽度加起来的总宽度,然后设置为包裹该父元素的宽度。
那么问题来了?是该用非常准确的 getBoundingClientRect 的 width
还是用 width
, 还是 取整的 clientWidth
呢?
我当时是用了 width
这个属性,因为考虑到这里只是简单的横向布局,没必要获取太详细的值,并没什么太大的意义。当然了,取 getBoundingClientRect 的 width 也是可以的。
getBoundingClientRect
首先我们知道,getBoundingClientRect
获取的最精确的值。也就说,你需要获取分毫不差的值,进行某些操作,这时候往往是你的实现动画的时候。如下下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xnmY4ZYM-1633676828431)(lb8Nq0.gif)]
如果使用了不是很准确的值呢?结果获取的值误差越大,动画的效果和你想要的误差则越大。
clientWidth
这个的话,暂时没想到以后想到再补充吧!