提示:
文章目录
前言
需求:点击页面非弹窗区域,关闭弹窗,
问题:全局添加点击监听事件window.addEventListener(‘click’,()=>{console.log(‘点击页面!’)});,无法监听iframe被点击。
方案1:给iframe添加addEventListener
失败原因:无效
let TestIframe = document.getElementById('TestIframe');
TestIframe.addEventListener('click',()=>{console.log('iframe点击!')});
方案2:给iframe.contentDocument添加addEventListener
失败原因:谷歌浏览器更新后,无法获取iframe.contentWindow和iframe.contentDocument
let TestIframe = document.getElementById('TestIframe');
TestIframe.contentWindow.addEventListener('click',()=>{console.log('contentWindow点击!')});
方案3:使用postMessage
缺点:1、每个iframe都需要添加postMessage,2、部分iframe嵌套外部项目,无法进行postMessage添加。
方案4:监听iframe是否为当前document的activeElement,activeElement 属性返回文档中当前获得焦点的元素。
解决方案:通过全局点击事件监听和iftame监听activeElement,可实现页面点击监听
示例未作单独处理,正常情况下,打开弹窗,开启定时器setInterval,关闭弹窗,清除定时器clearInterval。
一、全局点击事件,无法监听iframe被点击。
浏览器同源策略,不然会报错
a.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>a</title>
<style>
.a_box{
height: 600px;
width: 600px;
background-color: #f00;
position: relative;
}
.a_inner{
position: absolute;
top: 50px;
left: 50px;
height: 500px;
width: 500px;
background: #000;
}
</style>
</head>
<body>
<div class="a_box">
<div class="a_inner">
<iframe id="TestIframe" height="100%" width="100%" src="http://127.0.0.1:5500//b.html" frameborder="0"></iframe>
</div>
</div>
<script>
window.addEventListener('click',()=>{console.log('点击页面!')});
</script>
</body>
</html>
b.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>b</title>
<style>
.b_box{
height: 400px;
width: 400px;
background-color: #ff0;
position: absolute;
top: 50px;
left: 50px;
}
</style>
</head>
<body>
<div id="bBox" class="b_box"></div>
</body>
</html>
二、解决方案
1、a.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>a</title>
<style>
.a_box{
height: 600px;
width: 600px;
background-color: #f00;
position: relative;
}
.a_inner{
position: absolute;
top: 50px;
left: 50px;
height: 500px;
width: 500px;
background: #000;
}
</style>
</head>
<body>
<div class="a_box">
<div class="a_inner">
<iframe id="TestIframe" height="100%" width="100%" src="http://127.0.0.1:5500/b.html" frameborder="0"></iframe>
</div>
</div>
<script>
window.addEventListener('click',()=>{console.log('点击页面!')});
let activeElement;
let iframeCheckTimer = setInterval(()=>{
if (document.activeElement) {
if(activeElement==document.activeElement)return
activeElement=document.activeElement;
if(activeElement&&activeElement.tagName=='IFRAME'){
console.log('iframe被激活');
}
}
},200);
</script>
</body>
</html>
b.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>b</title>
<style>
.b_box{
height: 400px;
width: 400px;
background-color: #ff0;
position: absolute;
top: 50px;
left: 50px;
}
</style>
</head>
<body>
<div id="bBox" class="b_box"></div>
</body>
</html>
点击黑色iframe区域(包括黄色区域),触发iframe监听console.log(‘iframe被激活’)
点击iframe以为区域(除黑色和黄色),触发全局监听console.log(‘点击页面!’)
三、试错过程
a.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>a</title>
<style>
.a_box{
height: 600px;
width: 600px;
background-color: #f00;
position: relative;
}
.a_inner{
position: absolute;
top: 50px;
left: 50px;
height: 500px;
width: 500px;
background: #000;
}
</style>
</head>
<body>
<div class="a_box">
<div class="a_inner">
<iframe id="TestIframe" height="100%" width="100%" src="http://127.0.0.1:5500//b.html" frameborder="0"></iframe>
</div>
</div>
<script>
let TestIframe = document.getElementById('TestIframe');
TestIframe.onload = ()=>{
let contentDocument = TestIframe.contentDocument;
let bBox = contentDocument.getElementById('bBox');
bBox.addEventListener('click',()=>{console.log('xxxxxxxxxxxxxxx')})
console.log(bBox);
}
</script>
</body>
</html>
b.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>b</title>
<style>
.b_box{
height: 400px;
width: 400px;
background-color: #ff0;
position: absolute;
top: 50px;
left: 50px;
}
</style>
</head>
<body>
<div id="bBox" class="b_box"></div>
</body>
</html>
平平无奇的获取iframe内元素,添加点击事件,完美~~
但是,但是,但是,在其他版本的谷歌,@_@报错了~~
总结
踩坑路漫漫长@~@