记一次requestFullScreen踩坑

踩坑背景:项目需求一个echarts图标组件,后期为了用户体验,新增了全屏切换的功能

技术实现:采用了js内置方法,requestFullScreen来实现的某个容器的最大化,
踩坑之路:由于使用的时element的ui库,图标组件中有使用了select组件和dropdowm组件作为了用户进行筛选的工具, 进行全屏的是整个根元素,全屏切换功能完美实现,看似一切正常, 但是当全屏后才发现select和Dropdowm下拉的内容竟然没有被显示出来,,
初始怀疑是由于层级不够,打开后台发现层级没有问题,那是什么原因呢?看了下布局 ,幡然醒悟, 原来类似select下来组件默认是不包含在你组件的根元素上面的 ,而是和#app同级被插入到body下面的,那么当你的app被全屏了以后,会被创建一个新的文档流,
而这个文档流将不受你的定位和层级影响,默认会推到最外面,就是离用户最近的一个层面上,这也可以理解浏览器的这种机制,当某个元素被最大化以后,用户肯定是想更细的查看这个元素,如果没有这种推到最外面的机制的化,很有可能因为其他元素的层级高于他,

而使得你全屏的效果怪异,这也是为啥全屏以后的元素摆脱的定位等一些样式的控制,究其原因就是因为select和模态框之类的组件默认会被插到body下面,而不属于你app的子元素,导致了app全屏以后会遮挡不是他子元素的所有其他的元素,
结局方案,1:将全屏元素更改为body,此时全屏的是整个body而非app,这样就不会遮挡
                  2:select等组件默认值是插到body,但是可以设置为不插入body而是隶属与你代码层面的父元素, 例入设置dialog的append-to-body的值 ,具体参考饿了么的文档
 个人推荐使用第一中解决方案,因为不是所有的组件都支持append-to-body
有代码有真相:全屏切换(注意兼容写法,包括取消全屏的)

 handleFullscreen () {
      let main = document.body
      if (this.value:Boolean) {
        if (document.exitFullscreen) {
          document.exitFullscreen()
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen()
        } else if (document.webkitCancelFullScreen) {
          document.webkitCancelFullScreen()
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen()
        }
      } else {
        if (main.requestFullscreen) {
          main.requestFullscreen()
        } else if (main.mozRequestFullScreen) {
          main.mozRequestFullScreen()
        } else if (main.webkitRequestFullScreen) {
          main.webkitRequestFullScreen()
        } else if (main.msRequestFullscreen) {
          main.msRequestFullscreen()
        }
      }
posted @ 2020-09-28 11:38  因一人念一城  阅读(5029)  评论(0编辑  收藏  举报