HTML5技术

更靠谱的横竖屏检测方法 - Zsingsong

字号+ 作者:H5之家 来源:H5之家 2016-09-22 17:00 我要评论( )

前不久,做了一个H5项目,需要在横竖屏变化时,做一些处理。毫无疑问,需要使用 orientationchange 来监听横竖屏的变化。 方案一: // 监听 orientation changes window.addEventListener("orientationchange", function (event) { // 根据event.orientation

前不久,做了一个H5项目,需要在横竖屏变化时,做一些处理。毫无疑问,需要使用orientationchange来监听横竖屏的变化。

 方案一:

// 监听 orientation changes window.addEventListener("orientationchange", function(event) { // 根据event.orientation|screen.orientation.angle等于0|180、90|-90度来判断横竖屏 }, false);

代码添加上后,就各种兼容性问题。这里兼容性问题出现在两个地方:

  • orientationchange
  • event.orientation|screen.orientation.angle
  • 如下是orientationchange事件的兼容性:

    如下是screen.orientation的兼容性:

     

     

     方案二:

    上述方案不行,只能另行他法了。google一下,了解到可以通过resize配合(window.inner/outerWidth, window.inner/outerHeight)来实现:

    window.addEventListener("resize", function(event) { var orientation=(window.innerWidth > window.innerHeight)? "landscape":"portrait"; if(oritentation === 'portrait'){ // do something …… } else { // do something else …… } }, false);

    这种方案基本满足大部分项目的需求,但是还是有些不足之处:

  • 只要windowsize变化,就会不断触发触发resize事件。可以使用setTimeout来优化一下
  • 如果有多个地方需要监听横竖屏,就需要注册多个window.addEventListener("resize", function(event) {……})。能不能通过订阅与发布模式来改进一下,只注册一个resize负责监听横竖屏变化,只要横竖发生变化就发布通知订阅的对象。其他需要监听横竖屏的地方只需订阅一下即可。
  • 关键代码如下:

    var resizeCB = function(){ if(win.innerWidth > win.innerHeight){//初始化判断 meta.init = 'landscape'; meta.current = 'landscape'; } else { meta.init = 'portrait'; meta.current = 'portrait'; } return function(){ if(win.innerWidth > win.innerHeight){ if(meta.current !== 'landscape'){ meta.current = 'landscape'; event.trigger('__orientationChange__', meta); } } else { if(meta.current !== 'portrait'){ meta.current = 'portrait'; event.trigger('__orientationChange__', meta); } } } }();

    完整代码猛击这里

     

     方案三:

    不过个人觉得通过window.innerWidth > window.innerHeight来实现的是一种伪检测,有点不可靠。 可不可以通过浏览器来实现检测?如基于CSS3@media媒体查询来实现。

    如下@media兼容性:


    如上上图所示,移动端浏览器都支持CSS3 media。

    实现思路:

    这里我选择<html></html>的节点font-family作为检测样式属性。理由如下:

    这样我们就可以指定特定标识来标识横竖屏的状态,不过需要将指定的标识放置在其他字体的前面,这样就不会引起hmtl字体的变化。

    关键代码如下:

    resizeCB = function() { var hstyle = win.getComputedStyle(html, null), ffstr = hstyle['font-family'], pstr = "portrait, " + ffstr, lstr = "landscape, " + ffstr, // 拼接css cssstr = '@media (orientation: portrait) { .orientation{font-family:' + pstr + ';} } @media (orientation: landscape) { .orientation{font-family:' + lstr + ';}}'; // 载入样式 loadStyleString(cssstr); // 添加类 html.className = 'orientation' + html.className; if (hstyle['font-family'] === pstr) { //初始化判断 meta.init = 'portrait'; meta.current = 'portrait'; } else { meta.init = 'landscape'; meta.current = 'landscape'; } return function() { if (hstyle['font-family'] === pstr) { if (meta.current !== 'portrait') { meta.current = 'portrait'; event.trigger('__orientationChange__', meta); } } else { if (meta.current !== 'landscape') { meta.current = 'landscape'; event.trigger('__orientationChange__', meta); } } } }();

    完整代码猛击这里


    测试效果

  •  portrait效果:
  • landscape效果:
  •  

    方案四:

    可以再改进一下,在支持orientationchange时,就使用原生的orientationchange,不支持则使用方案三

    关键代码如下:

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • ajax跨子域请求的两种现代方法 - zhjh256

      ajax跨子域请求的两种现代方法 - zhjh256

      2016-09-07 13:00

    • ios h5 app avalon tap点击事件失效及点击延迟300ms问题解决方法 - xuejianxiyang

      ios h5 app avalon tap点击事件失效及点击延迟300ms问题解决方法 - x

      2016-08-31 18:00

    • document.querySelector和querySelectorAll方法 - 贵欢lucky

      document.querySelector和querySelectorAll方法 - 贵欢lucky

      2016-08-04 10:00

    • 常见的前端图像显示方法 - 水之君

      常见的前端图像显示方法 - 水之君

      2016-07-29 10:00

    网友点评
    )