mirari / vue-fullscreen

A simple Vue.js component for fullscreen
MIT License
439 stars 50 forks source link

全屏元素含iframe时,teleport设置为啥都有bug #42

Closed DanPeony007 closed 2 years ago

DanPeony007 commented 2 years ago

当全屏元素中有 iframe 嵌入页面时,设置 teleport 为啥都有问题。teleport 为 false 时 elementUI 的提示框看不到,teleport 为 true 时 iframe 中的 body 被删成空内容没了......


未全屏时: 未全屏时


全屏时: 全屏body消失

mirari commented 2 years ago

两张图看上去没有区别啊,全屏对象是什么,使用的是组件还是指令模式? 最好能提供复现的简单示例。 参考 https://codepen.io/mirari/pen/VwjyKPL

DanPeony007 commented 2 years ago

不好意思,不好意思,图贴错了,2张都贴的是未全屏的。(感谢作者查看) 上面图片更新了,全屏时 iframe 中的 body 元素中内容为空了

全屏对象:是元素中 document中类名为 document-wrapper 这个元素。 使用方式:指令模式

两张图看上去没有区别啊,全屏对象是什么,使用的是组件还是指令模式? 最好能提供复现的简单示例。 参考 https://codepen.io/mirari/pen/VwjyKPL

mirari commented 2 years ago

如果iframe是一个独立页面,全屏切换应该是没问题的 https://codepen.io/mirari/pen/oNGLwBa 但是,这里有一个无法避免的问题是iframe在DOM中被移动时会导致重新加载,目前看上去是无解的。https://stackoverflow.com/questions/8318264/how-to-move-an-iframe-in-the-dom-without-losing-its-state

teleport的实现原理是触发全屏时将它移动到body根节点下,并将body全屏,从而避免一些动态创建的弹窗无法被看到的问题。 这个过程中被全屏的元素如果含有iframe,就无法避免被重新加载。 看上去这个iframe是动态创建的,这可能就需要一个重新初始化的动作来还原它被创建的整个过程。 可以在callback回调里做这个操作。

DanPeony007 commented 2 years ago

是的,估计是重新加载的原因。 但是我试过在callback中重新initTinymce并没有效果。 我添加了一个demo,链接为:https://github.com/DanPeony007/vue-fullscreen-issue-demo 首页就可以复现这个问题,大神有空可以看一下。 非常感谢~~

mirari commented 2 years ago

我试了下在callback里执行是有效的 应该是tinymce自己不支持重复init,需要先销毁

    fullscreenChange(fullscreen) {
      this.fullscreen = fullscreen
      this.$refs.tinymce.destroyTinymce()
      this.$refs.tinymce.initTinymce()
    }

但是这样其实仍然有问题,如果用户已经编辑过内容,销毁重建会丢失数据。

另一个思路是不使用teleport,全屏目标是body,然后在回调中为你的目标元素添加一个样式,用绝对定位的形式将其撑满屏幕。这样既不会影响弹出框,也不会触发iframe刷新。

DanPeony007 commented 2 years ago

非常感谢作者的耐心解答。 我试过,第一种方式确实可以,先销毁再重建。 但是还是有一些担心,会影响到数据一致性(有编辑页面全屏演示)。最终决定使用你推荐的这个思路,不使用teleport,将body全屏,目标元素定位。 非常感谢~