您的位置:首页 > Web前端 > CSS

js - js+css实现横竖屏变换自动使用不同样式

2018-01-14 00:07 381 查看
今晚我在写一个页面, 要求是在用户旋转屏幕的时候应用不同的样式,让网页更好地表现内容. 难点不在于根据横竖屏来设置不同的样式, 而是在于在用户旋转屏幕之后需要刷新一下才能应用新的样式, 这样贼麻烦.
因此今晚搞了两个小时, 终于实现在旋转屏幕的时候自动切换样式了

首先, 我写的这个页面在dom加载完成后会获取当前屏幕的宽度进行计算rem. 也就是说, 如果用户第一次打开这个网页是竖着看的时候, 是根据手机上的短边(屏幕宽度)来计算的.(通过设置html的font-size)
(function page_first() {
//设置font-size 1rem = 10vw
document.addEventListener('DOMContentLoaded', function() {
document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
}, false);
}());这里我设置为屏幕宽度=10rem, 这样子好计算

接下来, 我写了个@media的css样式, 设置了一下横屏和竖屏样式
@media screen and (orientation: portrait) {
/* 竖屏样式 */
}
@media screen and (orientation: landscape) {
/* 横屏样式 */
}

那么这时候我就看了一下效果结果是, 我竖屏的时候正常显示(是我要的效果), 当我切换横屏的时候, 还是竖屏的样式, 直到我刷新了一下, 才显示了横屏的样式.
总是刷新很不爽, 我想要自动改变样式, 那么绑定一个事件( onorientationchange )
addEventListener('orientationchange', function() {
location.reload(false);
});注: location.reload()参数设置为false(默认), 会从本地获取之前加载好的页面进行重新渲染(刷新); 设置为true则重新向服务器获取页面(GET方法获取页面), 不用本地的, 相当于按了一下F5
 
我这时候又看了一下效果.
还是不行, 老样子, 按理说没理由啊? 还缺了什么?
后来脑袋一拍, 原来我的rem单位是按手机显示范围的短边算的, 当然没变化, 于是我把开头那个代码在加进去, 重新计算一次rem值再刷新.
// 当横竖屏变换时,从缓存中获取资源刷新页面
addEventListener('orientationchange', function() {
//先重新计算rem跟屏幕宽度,然后再刷新
(function page_first() {
document.addEventListener('DOMContentLoaded', function() {

a4f7
document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
}, false);
}());
location.reload(false);
});

我再看了一下, 好了!

总结一下: 如果光写css横竖屏样式的话, 用户旋转屏幕还是需要刷新才能获得相应的样式, 我现在用的是根据屏幕计算rem的方式, 因为计算出的rem已经固定了, 之后刷新还是应用之前的rem值 (屏幕实际宽度跟rem的比值) ,那么我需要绑定旋转屏幕事件, 然后在用户旋转完屏幕之后再获取一次rem值, 最后才刷新, 这样就能得出想要的页面了.

这次就这么多, 前后搞了2个小时~~感觉自己有时候还是蠢萌蠢萌的 (@^@)

/* 17-1-21更新 */
洗澡的时候突然想到, 好像@media自动会检测状态的, 那么我在js里面不需要刷新, 直接重新计算rem就好了, 于是出来后把刷新的那行代码删掉了, 结果是可用, 速度变快了点
最终代码更改为
// 当横竖屏变换时,从缓存中获取资源刷新页面
addEventListener('orientationchange', function() {
//先重新计算rem跟屏幕宽度,然后再刷新
(function page_first() {
document.addEventListener('DOMContentLoaded', function() {
document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
}, false);
}());
});那么我就奇怪了, 为什么之前我开始的时候需要刷新一下? 即使rem不对那也只是放大了啊

/*18-1-30 更新*/
在回看代码的时候发现,自己干了多余的一步,我应该把绑定在orientationchange中的DOMContentLoad事件删除去
应该要这样子addEventListener('orientationchange', function () {
//先重新计算rem跟屏幕宽度,然后再刷新
if (window.innerWidth === window.DEVICEWIDTH) return 0;
window.DEVICEWIDTH = window.innerWidth;
document.getElementsByTagName('html')[0].style.fontSize = window.DEVICEWIDTH / 10 + 'px';
location.reload(false);
});我这几天参考了别人的代码, 其中有提过兼容问题, 主要操作就是判断浏览器orientation和orientationchange能不能支持, 如果不能(针对IE8-) 就用resize事件, 获取一次屏幕宽度,跟之前获取的是否一样, 不一样就应用不同的样式
我不需要兼容IE8-, 但是觉得这个想法不错, 于是我就改了一下
上面代码中的window.DEVICEWIDTH是我在页面加载的时候首次获取的window.innerWidth, 现在当事件触发之后,我又比对了一次,如果没改变(屏幕180度旋转,那么我就直接返回, 触发但不处理这次的事件), 这次我又加回去了location.reload(false), 主要是我的页面是用于微信内部浏览器的, 这个x5内核的浏览器实在太奇怪了, 为了兼容它浪费点性能也只能加上了(无奈)
以上!

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: