一文看懂js中元素的客户区大小(clientWidth,clientHeight)
元素的客户区
元素的客户区大小,指的是元素内容及其内边距所占据的空间大小。
相关属性如下:
1. clientWidth:元素内容区宽度+元素左右内边距
2. clientHeight:元素内容区高度+元素上下内边距
案例代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } .parent { width: 500px; height: 500px; margin: 100px auto; background-color: red; border: 10px solid #000; overflow: hidden; } .child { width: 300px; height: 300px; border: 10px solid #000; padding: 10px; margin: 50px 90px; background-color: green; } </style> </head> <body> <div class="parent"> <div class="child"></div> </div> <script> var child = document.querySelector('.child'); var html = ''; html += 'clientHeight=' + child.clientHeight + "<br>"; html += 'clientWidth=' + child.clientWidth + "<br>"; child.innerHTML = html; </script> </body> </html>
结果如下:
我们不难发现一个现象元素的offsetwidth=元素的clientWidth+左右边框长度,offsetTop同理。
因为元素的offsetWidth = 元素的宽+左右内边距宽度+左右边框宽度
即使在怪异盒模型下也成立:
代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } .parent { width: 500px; height: 500px; margin: 100px auto; background-color: red; border: 10px solid #000; overflow: hidden; } .child { width: 300px; height: 300px; border: 10px solid #000; padding: 10px; margin: 50px 90px; background-color: green; /*注意这里*/ box-sizing: border-box; } </style> </head> <body> <div class="parent"> <div class="child"></div> </div> <script> var child = document.querySelector('.child'); var html = ''; html += 'clientHeight=' + child.clientHeight + "<br>"; html += 'clientWidth=' + child.clientWidth + "<br>"; html += "offsetWidth=" + child.offsetWidth + "<br>"; html += "offsetHeight=" + child.offsetHeight + "<br>"; child.innerHTML = html; </script> </body> </html>
结果如下:
现给出一个确定浏览器窗口大小的函数:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> function getViewport() { if (document.compatMode === 'BackCompat') { return { width: document.body.clientWidth, height: document.body.clientHeight } } else { return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight } } } console.log(getViewport()); </script> </body> </html>
结果如下:
这里检查document.compatMode属性,判断浏览器是否运行在混杂模式。
在这里我们改写一下该函数:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> function getViewport() { if (document.compatMode === 'BackCompat') { getViewport = function () { return { width: document.body.clientWidth, height: document.body.clientHeight } } } else { getViewport = function () { return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight } } } return getViewport(); } console.log(getViewport()); </script> </body> </html>
改造之后我们同样能获取对应的结果,改写之后,我们在调用getViewport的时候,就不会进行判断了。我们知道程序中没有if判断的代码往往比有if判断的代码运行的时候,性能会高一点。
我们在改造一下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> var getViewport = (function () { if (document.compatMode === 'BackCompat') { return function () { return { width: document.body.clientWidth, height: document.body.clientHeight } } } else { return function () { return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight } } } })(); console.log(getViewport()); </script> </body> </html>
现在这个函数达到了改造一的效果,优化了性能。
其实这两次改造都提升了代码的性能,我们把这种技巧叫做惰性载入函数。
改造一在第一次运行的时候会消耗一下性能,改造二最开始的时候会消耗一下性能,至于采用那种方式进行优化,取决于具体需求。
举个例子:假如这个方法我是一定要使用的,那么可以使用第二种改造,假如这个方法我不一定会使用到,那么可以使用第一种改造。
关于元素客户区大小的知识点差不多就是这样子,如有错误,请告知一下,好及时修改。顺便扯了一下js的高级技巧,我觉得只要能从一个知识点联想到另一个知识点就是好事。
累积知识点,解决每一个遇到的问题,实现从量变到质变