有个项目需求是:腾翔插件在ie中进行pdf的展示,实现缓存,而且会很有多弹框的出现,十分的烦恼。而且ie的调试基本上和没有一样,增加了调试难度和卡顿。这次记录一下是如何处理:object引入控件层级很高,在弹框之上,那要如何展示弹框的内容呢?
那就需要iframe出场了,iframe可以在object之上,不展示内容,进行一个覆盖。
这里采用的是vue2技术,封装组件实现的。也需要借助js的observer监听。
首先 pdf.vue 组件。
<div id="notify" class="errInfo" v-show="isTxErr && !noNeedFrame">
<iframe allowtransparency="true" class="newiframe" src="" frameborder="0"></iframe>
</div>
<div class="frame" v-if="show" v-loading="frameLoading">
<object id="webPDFObj" ref="webPDFObj" :data-key="keyname2" classid="CLSID:6EE0E832-A96C-480C-AE0A-EB35A9BB9652" width="100%" height="100%">
<param name="wmode" value="window">
</object>
</div>
object控件本身可以正常使用,切换过程中要确保控件加载完毕,不然会出现单独弹框脱离ie打开的情况。v-if不行。width为0可以尝试。
iframe在object之上,大小盖住object。当有弹框时就显示iframe,那时object就在iframe之下了。
不过,怎么监听弹框出现呢,如果出现了多个弹框呢,那就需要万能的js来了。
const _this = this
let MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
if (this.observer) this.observer.disconnect()
this.observer = new MutationObserver(list => {
list.forEach(mutation => {
let earr = document.getElementsByClassName('el-dialog__wrapper')
let res = Array.from(earr).filter((el) => {
let cname = el.className
if (cname.includes('txpdfShow')) { // 排除 txpdfShow 项
return false
} else {
return window.getComputedStyle(el).display !== 'none'
}
})
let element = res ? res[0] : undefined
let poparr = document.getElementsByClassName('el-popper')
let res1 = Array.from(poparr).filter((el) => {
return window.getComputedStyle(el).display !== 'none'
})
let element2 = res1 ? res1[0] : undefined
let drawarr = document.getElementsByClassName('el-drawer__wrapper')
let res2 = Array.from(drawarr).filter((el) => {
return window.getComputedStyle(el).display !== 'none'
})
let element3 = res2 ? res2[0] : undefined
if (element2 || element || element3) {
_this.$store.dispatch('changeIsTx', true)
} else {
_this.$store.dispatch('changeIsTx', false)
}
})
})
this.observer.observe(document.body, { attributes: true, subtree: true, attributeFilter: ['style'] })
我这里是封装了一个js,通过MutationObserver来监听dom的变化,监听返回变化的元素,进行排查,有弹框,悬浮等内容的都可以监听到,然后设置全局变量,进行iframe的控制。
不过这里还要注意,有些特殊弹框,比如,弹框是嵌套的,弹框里有引入控件的,这些需要我们单独处理,不然控件永远在iframe下,就一片空白了。
弹框嵌套的,进行一个拆开,本来弹框应该是相互独立的。确保是一个弹框改变。
弹框中有控件的,同时满足需要展示,有弹框iframe又遮挡的,那就需要加个class,比如txpdfShow,来帮我们监听时放过它,让它展示。
我还遇到,弹框下是object控件,弹框上还是object控件。(别问,问就是这样设计的。。。)
那就单独的在弹框内部加个同等大小的iframe吧,控制组件已经不行了,毕竟,弹框上下状态是一致的。