iframe添加addEventListener无效、获取Iframe的contentWindow和contentDocument失败,不使用postMessag,如何监听iframe点击事件

提示:


前言

需求:点击页面非弹窗区域,关闭弹窗,

问题:全局添加点击监听事件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内元素,添加点击事件,完美~~
在这里插入图片描述
在这里插入图片描述
但是,但是,但是,在其他版本的谷歌,@_@报错了~~
在这里插入图片描述

总结

踩坑路漫漫长@~@

  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值