点击iframe内表单按钮后EventListener失效问题求助
问题描述
主页面通过window.onload给iframe内id为hidepopout的按钮绑定了PopUpHide事件监听器,该方法可隐藏iframe并重置表单。但点击iframe内表单中id为sendmsg的按钮提交表单后,再点击hidepopout按钮就无法隐藏iframe了,事件监听器似乎失效——未点击sendmsg按钮时功能完全正常。
主页面HTML代码
<!DOCTYPE html> <html lang="en-US" prefix="og: http://ogp.me/ns#"> <head> <script> $(document).ready(function(){ $("#popup1").hide(); }); window.onload=function(){ document.getElementById("popup1").contentWindow.document.getElementById("hidepopout").addEventListener("click", PopUpHide, false); function PopUpHide(){ $("#popup1").hide(); document.getElementById("popup1").contentWindow.document.getElementById("form").reset(); } } </script> </head> <body> <iframe class="b-popup" id="popup1" src="index2.php" title="contact form"></iframe> <button onclick="PopUpShow()">Contact me</button> <script> function PopUpShow(){ $("#popup1").show(); } </script> </main> <footer></footer> </div> </body> </html>
iframe页面index2.php代码
<html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="../CSS/Form.css"> <title>Contact Us</title> </head> <body> <?php if (!empty($success)) {?> <div class="alert alert-success">Your message was sent successfully!</div> <?php }?> <?php if (!empty($error)) {?> <div class="alert alert-danger"><?= $error ?></div> <?php }?> <button id="hidepopout">✖</button> <form id="form" method="post" action="submit.php"> <button id="sendmsg" class="btn btn-primary btn-block">Send Message</button> </form> </body> </html>
原因分析
点击sendmsg按钮提交表单后,iframe页面会同步刷新(表单默认提交方式会重新加载页面),原来绑定在hidepopout按钮上的事件监听器是主页面在初始加载时绑定的,页面刷新后原DOM元素被全新替换,之前绑定的事件自然失效。
解决方法
方法1:在iframe内部绑定事件(推荐)
直接在index2.php中给hidepopout按钮绑定事件,通过window.parent调用主页面的全局方法:
- 主页面修改:把
PopUpHide改成全局可访问的函数,移除原window.onload内的事件绑定代码
// 移到window.onload外部,成为全局函数 function PopUpHide(){ $("#popup1").hide(); document.getElementById("popup1").contentWindow.document.getElementById("form").reset(); } window.onload=function(){ // 这里不再需要绑定iframe内的事件 }
- iframe页面(index2.php)添加脚本:
<!-- 在index2.php的body末尾添加 --> <script> document.getElementById('hidepopout').addEventListener('click', function() { window.parent.PopUpHide(); }); </script>
方法2:监听iframe加载事件,重复绑定
如果坚持在主页面处理,监听iframe的load事件,每次页面刷新后重新绑定事件:
window.onload=function(){ bindHideEvent(); } // 封装绑定逻辑 function bindHideEvent(){ const iframe = document.getElementById("popup1"); iframe.contentWindow.document.getElementById("hidepopout").addEventListener("click", PopUpHide, false); } // 监听iframe加载,每次刷新后重新绑定 document.getElementById("popup1").addEventListener('load', bindHideEvent); function PopUpHide(){ $("#popup1").hide(); document.getElementById("popup1").contentWindow.document.getElementById("form").reset(); }
额外优化方案
将表单改成AJAX异步提交,这样iframe页面不会刷新,原有事件监听器会一直有效,同时用户体验更流畅。
内容的提问来源于stack exchange,提问作者Ophelia
相关产品推荐
相关产品推荐

