移动手机web页面转屏事件兼容解决方案

我们知道mobile设备上监测转屏的事件是orientationchange,但这个事件支持得不太好,有些android就不支持orientation事件

zepto.js中扩展了一个 $.support 来检测是否支持orientation

  View Code

 

本文通过Javascript的window.matchMedia方法 和 css media query 来有效的处转屏兼容:

window.matchMedia 和 media (淘宝的响应式就是用的这个)请参考 https://github.com/gmuteam/GMU/wiki/Media-Query%E5%92%8CmatchMedia%E4%BB%8B%E7%BB%8D 、http://www.w3ctech.com/p/982

思路如下:

1、 为页面添加检测元素 ,css media query主要还是在style上起作用,故在页面创建一个div,作为media query作用的对象

1
$mediaElem = $( '<div class="'  + cls + '" id="'  + id + '"></div>' ).appendTo( 'body' )

2、 为检测元素添加transition样式及media query样式 ,当query条件满足时,去动态修改transition作用的属性,如(width),则可触发transitionEnd事件,这样则相当于可以监测到media query。

$style = $( '<style></style>' ).append( '.'  + cls + '{'  + cssPrefix + 'transition: width 0.001ms; width: 0; position: absolute; top: -10000px;}\n' ).appendTo( 'head' ); 
 
$style.append( '@media '  + query + ' { #'  + id + ' { width: 1px; } }\n' )

3、 注册transitionEnd事件 ,在检测元素上注册transitionEnd事件

1
2
3
4
5
6
$mediaElem.on(transitionEnd, function () {
     ret.matches = $mediaElem.width() === 1;
     $.each(listeners, function  (i,fn) {
         $.isFunction(fn) && fn.call(ret, ret);
     });
});

4、封装addListener及removeListener接口  主要记录在闭包中的listeners数组件,添加和删除回调函数即可

  

1
2
3
4
5
6
7
8
9
10
11
12
13
ret = {
     matches: $mediaElem.width() === 1 ,
     media: query,
     addListener: function  (callback) {
         listeners.push(callback);
         return  this ;
     },
     removeListener: function  (callback) {
         var  index = listeners.indexOf(callback);
         ~index && listeners.splice(index, 1);
         return  this ;
     }
};

 

完整源码: 

复制代码
(function ($) {
    /**
     * 定义,对matchMedia方法进行了封装。原理是用css media query及transitionEnd事件来完成的。在页面中插入media query样式及元素,当query条件满足时改变该元素样式,同时这个样式是transition作用的属性,
     * 满足条件后即会触发transitionEnd,由此创建MediaQueryList的事件监听。由于transition的duration time为0.001ms,故若直接使用MediaQueryList对象的matches去判断当前是否与query匹配,会有部分延迟,
     * 建议注册addListener的方式去监听query的改变。$.matchMedia的详细实现原理及采用该方法实现的转屏统一解决方案详见
     * 返回值MediaQueryList对象包含的属性<br />
     * - ***matches*** 是否满足query<br />
     * - ***query*** 查询的css query,类似\'screen and (orientation: portrait)\'<br />
     * - ***addListener*** 添加MediaQueryList对象监听器,接收回调函数,回调参数为MediaQueryList对象<br />
     * - ***removeListener*** 移除MediaQueryList对象监听器<br />
     * @method $.matchMedia
     * @grammar $.matchMedia(query)  ? MediaQueryList
     * @param {String} query 查询的css query,类似\'screen and (orientation: portrait)\'
     * @return {Object} MediaQueryList
     * @example 
     * $.matchMedia('screen and (orientation: portrait)').addListener(fn);
     */
    $.matchMedia = (function() {
        var mediaId = 0,
            cls = 'gmu-media-detect',
            transitionEnd = $.fx.transitionEnd,
            cssPrefix = $.fx.cssPrefix,
            $style = $('<style></style>').append('.' + cls + '{' + cssPrefix + 'transition: width 0.001ms; width: 0; position: absolute; top: -10000px;}\n').appendTo('head');

        return function (query) {
            var id = cls + mediaId++,
                $mediaElem,
                listeners = [],
                ret;

            $style.append('@media ' + query + ' { #' + id + ' { width: 1px; } }\n') ;   //原生matchMedia也需要添加对应的@media才能生效
            if ('matchMedia' in window) {
                return window.matchMedia(query);
            }

            $mediaElem = $('<div class="' + cls + '" id="' + id + '"></div>')
                .appendTo('body')
                .on(transitionEnd, function() {
                    ret.matches = $mediaElem.width() === 1;
                    $.each(listeners, function (i,fn) {
                        $.isFunction(fn) && fn.call(ret, ret);
                    });
                });

            ret = {
                matches: $mediaElem.width() === 1 ,
                media: query,
                addListener: function (callback) {
                    listeners.push(callback);
                    return this;
                },
                removeListener: function (callback) {
                    var index = listeners.indexOf(callback);
                    ~index && listeners.splice(index, 1);
                    return this;
                }
            };

            return ret;
        };
    }());
})(Zepto);
/**
 * @file 扩展转屏事件
 * @name ortchange
 * @short ortchange
 * @desc 扩展转屏事件orientation,解决原生转屏事件的兼容性问题
 * @import lib/zeptov1.0.js, lib/zepto.extend.js
 */
$(function () {
    /**
     * @name ortchange
     * @desc 扩展转屏事件orientation,解决原生转屏事件的兼容性问题
     * - ***ortchange*** : 当转屏的时候触发,兼容uc和其他不支持orientationchange的设备,利用css media query实现,解决了转屏延时及orientation事件的兼容性问题
     * $(window).on('ortchange', function () {        //当转屏的时候触发
     *     console.log('ortchange');
     * });
     */
    //扩展常用media query
    $.mediaQuery = {
        ortchange: 'screen and (width: ' + window.innerWidth + 'px)'
    };
    //通过matchMedia派生转屏事件
    $.matchMedia($.mediaQuery.ortchange).addListener(function () {
        $(window).trigger('ortchange');
    });
});
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,我会用中文回答你的问题。 Uniapp 中的 web-view 组件可以用来在小程序中展示网页内容。在 web-view 中播放视频时,如果不希望视频进入全屏横屏模式,可以在网页端的视频标签中加入如下属性来禁止全屏横屏模式: ``` <video playsinline webkit-playsinline> ``` 这样在 web-view 中播放的视频就不会进入全屏横屏模式了。 希望这个回答能帮到你! ### 回答2: uniapp的web-view组件在播放视频时,全屏显示的方式并不是强制横屏模式。在uniapp中,web-view组件是基于WebView技术实现的,它会在应用内嵌一个浏览器窗口,使用此组件可以在页面中加载并显示指定URL的网页内容。 针对web-view组件在播放视频时全屏显示的方式,uniapp并没有提供直接的横屏模式的支持。但是我们可以通过一些额外的方法来实现视频的横屏全屏效果。 一种可能的解决方案是利用uniapp提供的原生插件功能。可以通过编写原生的插件代码,针对特定设备平台进行横屏模式的支持。通过调用原生插件提供的接口,在视频播放时切换为横屏模式,从而实现全屏显示。 另一种可行的方法是通过使用特定的CSS样式来实现全屏显示。在视频播放时,通过添加CSS样式,将web-view组件的宽度和高度设置为100%或者屏幕尺寸的宽度和高度。这样,视频内容将会占据整个屏幕空间,实现全屏显示效果。 需要注意的是,不同设备和浏览器对于web-view组件的支持和显示效果可能会有所差异。因此,在实际开发中,需要对不同设备和平台进行兼容性测试,确保视频全屏显示的效果能够符合预期。 总结起来,uniapp的web-view组件在视频全屏显示方面并不是强制横屏模式,但我们可以通过原生插件或者CSS样式的方式来实现横屏全屏效果。希望以上回答能够对你有所帮助! ### 回答3: 在UniApp中,使用web-view组件嵌入网页中的视频播放器,通常情况下点击全屏按钮会触发视频进入全屏模式,但该全屏模式并非横屏模式。 UniApp的web-view组件是基于系统的WebView实现的,而WebView在移动设备上的全屏模式表现是根据系统的设置和浏览器的支持而定的。在大多数移动浏览器中,进入全屏模式会让网页占据整个屏幕,但并不一定会自动旋转屏幕为横屏模式。 要实现web-view中的视频全屏横屏播放效果,可以考虑以下解决方案: 1. 监听web-view的全屏事件:在进入全屏时,使用uni.hideTabBar()隐藏底部的导航栏,调用uni.setScreenOrientation({orientation: 'landscape'})进行屏幕旋转为横屏模式,同时将web-view的width和height设置为100vw和100vh,使其占满整个屏幕。 2. 自定义视频播放器控件:通过uni.ui或uni.ui-palette自定义视频播放器,在全屏按钮点击时,通过uni.requestFullScreen接口请求全屏模式,并手动旋转屏幕为横屏模式。 需要注意的是,以上方案仅在移动设备上生效,PC端的Web平台对于全屏模式可能有不同的实现方式。另外,不同浏览器对于WebView中的全屏模式支持程度可能不同,建议在开发过程中进行测试和兼容性处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值