项目场景:vue + element + iframe
问题描述
header上有element的浮窗(dropdown和popover)打开浮窗后,点击浮窗外的区域浮窗都会关闭,但是点击iframe的区域浮窗就不会关闭。
iframe属于第三方的页面,改不了他的代码,就不能点击后发送postmessage。
解决方案:
//放在data里面
IframeOnClick: {
resolution: 200,
iframes: [],
interval: null,
Iframe: function () {
this.element = arguments[0];
this.cb = arguments[1];
this.hasTracked = false;
},
track: function (element, cb) {
this.iframes.push(new this.Iframe(element, cb));
if (!this.interval) {
var _this = this;
this.interval = setInterval(function () {
_this.checkClick();
}, this.resolution);
}
},
checkClick: function () {
if (document.activeElement) {
var activeElement = document.activeElement;
for (var i in this.iframes) {
if (activeElement === this.iframes[i].element) {
// user is in this Iframe
if (this.iframes[i].hasTracked == false) {
this.iframes[i].cb.apply(window, []);
this.iframes[i].hasTracked = true;
}
} else {
this.iframes[i].hasTracked = false;
}
}
}
},
};
// mounted中调用
this.IframeOnClick.track(document.getElementById("iframeId"), ()=>{
alert("a click");
this.$refs.popoverRef.doClose();//popover关闭方法
this.$refs.dropdownRef.hide();//dropdown关闭方法
});
主要利用了document.activeElement(JavaScript中document.activeELement焦点元素介绍_JavaScript_脚本之家)。
mounted中调用的track方法,会在iframes中保存iframe的element作于比对活跃元素,cb为回调函数,hasTracked为判断点击标识,并且循环执行checkClick。
setInterval循环监听当前活跃元素是否是存在 iframes 中的元素,如果是,且hasTracked为false时才执行回调函数 。当点击iframe之外后hasTracked重置为false,再点击iframe之后会重新执行回调函数