巧妙使用CSS媒体查询(Media Queries)和JavaScript判断浏览器设备类型的好方法

有无数的理由要求我们在任何时候都应该知道用户是使用的什么设备浏览我们的网站——宽屏,普通屏,平板,手机?知道这些特征,我们web应用的CSS和JavaScript才能同步做相应的操作。在给Mozilla Developer Networks改版设计的过程中,我发现使用CSS媒体查询(media queries)虽然非常的有效,但有时,JavaScript却不能及时知道用户浏览设备的状态。浏览网站的用户使用的是桌面电脑,还是平板,还是手机?这对于CSS来说很容易,但CSS却无法将这些信息告诉JavaScript。我发明了一种基于CSS媒体查询和z-index属性的方法,能告诉JavaScript用户当前使用的是什么屏幕,这样我能调整JavaScript的动作来响应这种屏幕尺寸。

CSS代码

首先最重要的还是CSS媒体查询代码。这里只是示例,我们创建了三个媒体查询规则(但不包括缺省的“all”),它能控制四种屏幕情况:桌面(这是缺省状态,不需要媒体查询规则),“小屏幕”,平板,手机。针对每一种屏幕,我们给它一种不同的z-index值,这个值我们可以用JavaScript检测到。我们把这个元素定位到屏幕外,这样它就不会显示出来;记住,它的作用就是存放z-index值,我们要用javaScript获取这个值。

/* 缺省屏幕 */
.state-indicator {
    position: absolute;
    top: -999em;
    left: -999em;

    z-index: 1;
}

/* 小屏幕 */
@media all and (max-width: 1200px) {
    .state-indicator {
        z-index: 2;
    }
}

/* 平板 */
@media all and (max-width: 1024px) {
    .state-indicator {
        z-index: 3;
    }
}

/* 手机 */
@media all and (max-width: 768px) {
    .state-indicator {
        z-index: 4;
    }
}

每种z-index都在告诉我们的JavaScript当前的用户使用的是什么规格的屏幕。我们并不像知道用户究竟使用的是什么设备,因为你可以将浏览器宽度拉的很窄,但我们需要就是可视宽度,这样我们可以调整应用的布局。

JavaScript代码

也许你认为可以在DomContentLoaded时知道屏幕的大小,但我们需要实时知道屏幕的大小(因为用户会调整浏览器窗口的大小),我们需要有个方法获取当前窗口的属性:

// 创建状态指示元素
var indicator = document.createElement('div');
indicator.className = 'state-indicator';
document.body.appendChild(indicator);

// 获取设备类别的方法
function getDeviceState() {
    return parseInt(window.getComputedStyle(indicator).getPropertyValue('z-index'), 10);
}

使用这个方法,你就能检测出页面布局/js饰件中那些需要显示,那些需要隐藏。

if(getDeviceState() < 3) { // 如果是桌面电脑后小屏幕电脑
    // 显示js饰件....
}

有人也许会认为这些数字太容易搞错,让代码很难维护。其实我们可以用一个对象来处理这种事情:

function getDeviceState() {
    var index = parseInt(window.getComputedStyle(indicator).getPropertyValue('z-index'), 10);

    var states = {
        2: 'small-desktop',
        3: 'tablet',
        4: 'phone'
    };

    return states[index] || 'desktop';
}

这样,你就一个写出更具可读性的逻辑判断:

if(getDeviceState() == 'tablet') {
    // Do whatever
}

也许使用CSS的伪元素的content属性是个更好的方法:

.state-indicator {
    position: absolute;
    top: -999em;
    left: -999em;
}
.state-indicator:before { content: 'desktop'; }

/* 小屏幕桌面 */
@media all and (max-width: 1200px) {
    .state-indicator:before { content: 'small-desktop'; }
}

/* 平板 */
@media all and (max-width: 1024px) {
    .state-indicator:before { content: 'tablet'; }
}

/* 手机 */
@media all and (max-width: 768px) {
    .state-indicator:before { content: 'mobile'; }
}

用下面的JavaScript方法获取关键的内容:

var state = window.getComputedStyle(
    document.querySelector('.state-indicator'), ':before'
).getPropertyValue('content')

如何组织这些代码全看你自己了。如果你有一个全局对象,例如window.configwindow.app等,你可以把这些方法放到里面。我倾向于模块化这些功能,你可以把它做成jQuery插件或JavaScript工具包。不管你如何实现,它们都是你可以信赖的、简单易用的检测用户设备的好方法。

更上一层楼

我们知道屏幕尺寸会发生变化——用户手工调整浏览器大型或手机用户调整了手机方向,所以,当这些事件发生时,我们需要让系统告诉我们。下面这段简单的代码估计是你需要的:

var lastDeviceState = getDeviceState();
window.addEventListener('resize', debounce(function() {
    var state = getDeviceState();
    if(state != lastDeviceState) {
        // 保持当前的状态
        lastDeviceState = state;

        // 宣告状态变化,通过自定义的DOM事件或JS 消息发布/订阅模式,
        // 我喜欢后者,所有就假设使用了一个这样的工具库
        publish('/device-state/change', [state]);
    }
}, 20));

// 用法
subscribe('/device-state/change', function(state) {
    if(state == 3) { // or "tablet", if you used the object

    }
});

注意,这里我使用了debounce方法来执行resize事件发生时的动作——这对于性能来说非常重要。是使用自定义DOM事件还是使用发布/订阅模式,你自由选择,因为都很简单。

我觉得这种方法非常的好。有人可能会指出使用matchMedia也可以有相同效果,但问题是你需要在CSS里和JavaScript里都使用媒体查询,而有些媒体查询语句可能会很复杂,甚至会成为你的噩梦,不如使用简单的z-index。也有人会说可以使用 window.innerWidth来判断,但这样JS里获取的属性和CSS里的媒体查询就需要相互转换了,同样也会成为你的恶魔。我的方法的好处就在于你可以用它判断其他类型的媒体查询属性,例如检查手机是横向(landscape)还是竖向(portrait)。

不管怎样,你可以试一下,告诉我你的感觉!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用HTML、CSSJavaScript语言设计一个图书介绍网站时,可以按照以下步骤进行: 1. 首先,创建一个基本的HTML文件,命名为index.html,作为网站的主页。在主页中,可以包含网站的标题、导航栏和一些简单的介绍内容。 2. 创建一个CSS文件,命名为style.css,用于设置网站的样式。在CSS文件中,可以定义网站的颜色、字体、布局等样式。 3. 在主页中,可以添加一个图书列表页面,用于展示图书的封面、标题和简介。可以使用HTML的列表元素(如<ul>或<ol>)来展示图书列表,并使用CSS样式来美化列表的样式。 4. 创建一个JavaScript文件,命名为script.js,用于处理网站的交互功能。可以使用JavaScript来实现一些动态效果,比如点击图书封面时弹出图书详情的模态框。 5. 在主页中,可以添加一个图书详情页面,用于展示单个图书的详细信息。可以使用HTML的表格元素(如<table>)来展示图书的属性,并使用CSS样式来美化表格的样式。 6. 可以添加一个联系页面,用于展示网站的联系信息和反馈表单。可以使用HTML的表单元素(如<form>)来创建反馈表单,并使用CSS样式来美化表单的样式。 7. 在CSS文件中,可以使用媒体查询Media Queries)来实现响应式设计,使网站在不同设备上有良好的显示效果。 8. 最后,可以使用服务器端技术(如Node.js)将网站部署到服务器上,以便其他人可以访问和浏览。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值