Open phenomLi opened 6 years ago
在进行响应式网页开发时,利用@media screen设置屏幕断点是十分常用的做法:
@media screen
@media screen and (max-width: 768px) { /* your style */ }
@media screen可以判断当前设备的宽度然后使用定义的样式。 但是@media screen只能控制样式,不能控制逻辑。 假如现在有这么一个需求:在屏幕宽度小于768px时,出现弹框。 最常规的做法是用js检测屏幕:
window.onresize = function() { if(window.document.documentElement.clientWidth <= 768) { alert(window.document.documentElement.clientWidth); } };
可以看到当收缩视口时,会触发弹窗。 但是window.document.documentElement.clientWidth是一个不稳定的属性,他会受到padding,margin,和border以及浏览器设置的影响,有时候并不能精确地获取屏幕宽度的值。而且这种方法的可维护性很差,会造成JS和css的耦合严重,当css断点要改动时js也要一同改动。
window.document.documentElement.clientWidth
那么现在看起来判断屏幕断点的方法最好还是css,但是怎么样能够让css到达断点时通知js呢?用伪类做中介是一个完美的方法。
具体的思路是我们用@media query来动态改变某个元素的伪类,然后用js来获取这个元素的伪类的content,然后js根据获取到内容得到当前屏幕的断点。
@media query
content
首先我们在css设置三个屏幕断点:
@media screen and (max-width: 768px) { } @media screen and (max-width: 1024px) and (min-width: 768px){ } @media screen and (max-width: 1200px) and (min-width: 1024px) { }
然后我们用@media query动态地改变body的after:
body
after
body::after { content: ''; display: none; } @media screen and (max-width: 768px) { body::after { content: 'small'; } } @media screen and (max-width: 1024px) and (min-width: 768px){ body::after { content: 'middle'; } } @media screen and (max-width: 1200px) and (min-width: 1024px) { body::after { content: 'large'; } }
最后我们用js获取body的after的content里面的值:
const content = window.getComputedStyle(document.body, ":after").getPropertyValue("content"); if(content.indexOf('small') > -1) { //小屏幕 } if(content.indexOf('middle') > -1) { //中等屏幕 } if(content.indexOf('large') > -1) { //大屏幕 }
之所以上面要用indexOf而不是直接===是因为在某些浏览器下面用js获取到的content会包含双引号(比如会得到"small"而不是small)。
indexOf
===
"small"
small
然后现在我们试一试用这种方法来解决一开始提出的问题:在特定的断点弹窗。 不用改动很多东西,只要在js的判断里面加要的东西就行,简单直接,耦合成度也不高,然后为了更加直观到的效果我把它套进了onresize方法里面:
onresize
window.onresize = function() { const content = window.getComputedStyle(document.body, ":after").getPropertyValue("content"); console.log(content); if(content.indexOf('small') > -1) { alert(content); } if(content.indexOf('middle') > -1) { alert(content); } if(content.indexOf('large') > -1) { alert(content); } }
效果自然是棒棒哒。
在进行响应式网页开发时,利用
@media screen
设置屏幕断点是十分常用的做法:@media screen
可以判断当前设备的宽度然后使用定义的样式。但是
@media screen
只能控制样式,不能控制逻辑。 假如现在有这么一个需求:在屏幕宽度小于768px时,出现弹框。最常规的做法是用js检测屏幕:
可以看到当收缩视口时,会触发弹窗。
但是
window.document.documentElement.clientWidth
是一个不稳定的属性,他会受到padding,margin,和border以及浏览器设置的影响,有时候并不能精确地获取屏幕宽度的值。而且这种方法的可维护性很差,会造成JS和css的耦合严重,当css断点要改动时js也要一同改动。那么现在看起来判断屏幕断点的方法最好还是css,但是怎么样能够让css到达断点时通知js呢?用伪类做中介是一个完美的方法。
css通过伪类与js交互
具体的思路是我们用
@media query
来动态改变某个元素的伪类,然后用js来获取这个元素的伪类的content
,然后js根据获取到内容得到当前屏幕的断点。首先我们在css设置三个屏幕断点:
然后我们用
@media query
动态地改变body
的after
:最后我们用js获取
body
的after
的content
里面的值:之所以上面要用
indexOf
而不是直接===
是因为在某些浏览器下面用js获取到的content
会包含双引号(比如会得到"small"
而不是small
)。小试牛刀
然后现在我们试一试用这种方法来解决一开始提出的问题:在特定的断点弹窗。
不用改动很多东西,只要在js的判断里面加要的东西就行,简单直接,耦合成度也不高,然后为了更加直观到的效果我把它套进了
onresize
方法里面:效果自然是棒棒哒。