前言
我们之前已经实现了视频的静默播放以及结束播放的检测
现在我们开始尝试编写播放结束后自动关闭对话框
先回忆一下之前的代码
vdobj.hook('setup', function(player) {
console.log('setup',player)
// 绑定结束事件
player.on("ended", function() {
console.log('播放完毕')
});
});
根据内容来看,红色的是我们的视频
可以看到是一个iframe
那我们可以编写代码
使用postmessage进行通信
unsafeWindow.parent.postMessage('lhd_close')
同时在外部的iframe里进行监听,我们直接写在之前的OpenOriginDialog函数中
function OpenOriginDialog(Content){
return new Promise((resolve,reject)=>{
unsafeWindow.require(["Play"],function(Play){
let courseId=unsafeWindow._courseId;
let userId=unsafeWindow._userId;
let companyCode=unsafeWindow._companyCode;
const ListenMessage= (e)=> {
if(e.data==='lhd_close'){
unsafeWindow.removeEventListener('message', ListenMessage)
//关闭窗口代码
resolve()
}
}
unsafeWindow.addEventListener('message', ListenMessage);
Play.dialog({
//唯一ID
id:"videoBox-link",
data:{
url:Content.fullResUrl,
companyCode:companyCode,//三方公司id
resId:Content.id,
type:Content.mediaType,
userId:userId,
courseId:courseId,
title:Content.title+'-李恒道破解'
},
//弹出框宽度
width:"auto",
//弹出框高度
height:(screen.availHeight-200) + "px",
//是否开启打点功能
isTicker:true
});
})
})
}
这样就完成了
整理一下
大概逻辑是这样的
在调用打开对话框函数之后
我们做了以下几件事
1.对message进行监听,如果找到lhd_close则关闭对话框,并解除监听
2.打开对话框
3.对话框会加载一个iframe,在适当时机发送lhd_close让父级关闭对话框
那么我们的嵌套层级大概是这样的
但是根据我的测试,
青色的在不同的地址里可能出现第三次嵌套
所以我们需要对复杂环境进行判断
这里我直接编写了一个小函数
function EmitParentClose(){
let parentif=unsafeWindow.parent
while(parentif!==unsafeWindow.top){
parentif.postMessage('lhd_close')
parentif=parentif.parent
}
}
因为第一级也就是黄色部分,根据测试是没有任何用的
所以我们可以不对他发送
青色内部的不管多少层的iframe嵌套,如果触发退出时间
都会一直向上追溯直到完毕,每一层iframe都发送一次消息
那我们的通信部分就完毕了
接下来我们研究一下怎么关闭这个窗口
还是老规矩。搜一下标题class
我们找到了这里
发现了
//当弹出框隐藏时删除弹出框
$('#'+dialogId).on('hidden.bs.modal', function () {
$('#'+dialogId).remove();
})
也就是说当隐藏的之后直接调用remove函数
那dialogId是什么呢?
全局搜索一下找到了
var dialogId="dialog-myModal"+config.id+cacheNum;
前边的是固定的,后边是自动变化的
也就是说我们可以写一个css语句
document.querySelector('[id^=dialog-myModal]')?.remove()
这里用了id的前缀匹配,同时?是为了在找不到元素的情况下不调用remove,防止报错
那么我们再看一下OpenOriginDialog代码
function OpenOriginDialog(Content){
return new Promise((resolve,reject)=>{
unsafeWindow.require(["Play"],function(Play){
let courseId=unsafeWindow._courseId;
let userId=unsafeWindow._userId;
let companyCode=unsafeWindow._companyCode;
const ListenMessage= (e)=> {
if(e.data==='lhd_close'){
unsafeWindow.removeEventListener('message', ListenMessage)
document.querySelector('[id^=dialog-myModal]')?.remove()
resolve()
}
}
unsafeWindow.addEventListener('message', ListenMessage);
Play.dialog({
//唯一ID
id:"videoBox-link",
data:{
url:Content.fullResUrl,
companyCode:companyCode,//三方公司id
resId:Content.id,
type:Content.mediaType,
userId:userId,
courseId:courseId,
title:Content.title+'-李恒道破解'
},
//弹出框宽度
width:"auto",
//弹出框高度
height:(screen.availHeight-200) + "px",
//是否开启打点功能
isTicker:true
});
})
})
}
我们完成了对话框的打开关闭,以及子iframe的消息监听
而子video的代码也非常简单
我们只需要一个小修改
function EmitParentClose(){
let parentif=unsafeWindow.parent
while(parentif!==unsafeWindow.top){
parentif.postMessage('lhd_close')
parentif=parentif.parent
}
}
----以下为video的结束钩子代码---
vdobj.hook('setup', function(player) {
player.on("ended", function() {
EmitParentClose()
});
});
触发关闭条件的时候直接调用EmitParentClose函数即可。
结语
那么我们这节课就完成了iframe的监听
撒花~