我创建了一个页面,最终用户将通过 iframe 使用该页面。 在我创建的页面内有两个按钮“提交”和“拒绝”。单击拒绝按钮后,我想关闭 iframe。我尝试了几种方法,但由于跨源而出现权限被拒绝错误,因为我的网页将位于另一台服务器上,而将通过 iframe 使用我的页面的最终用户将位于不同的服务器上。
我尝试过的方法是
使用内容窗口,
窗口.父级
还尝试获取当前页面父网址并在同一页面重定向 window.top.href = window.top
这是一个 CSS 解决方案,使用
<nab>
上的覆盖层 (z-index
) <iframe>
、覆盖层中的按钮 (<label for="dismiss">
) 以及与 [hidden]
(<label for="dismiss">
) 关联的 <input id='dismiss'>
复选框)。一旦用户单击 <label for='dismiss'>
,<input id='dismiss'>
就会获得 :checked
,这会导致包含 <section>
的 <iframe>
消失。
html,
body {
overflow: hidden;
}
:checked+section {
width: 0vw;
height: 0vh;
left: -999vw;
}
section {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
nav {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 1;
width: 100%;
height: 100%;
overflow: hidden;
}
label {
display: block;
width: 7ch;
height: 2ch;
position: absolute;
top: calc(50% - 2.5ch);
bottom: 0;
right: 0;
left: 50%;
z-index: 12;
border: 2.5px outset grey;
border-radius: 6px;
font: 2.5ch/1 "Segoe UI";
text-align: center;
background: #fff;
cursor: pointer;
}
iframe {
display: block;
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
<input id='dismiss' type='checkbox' hidden>
<section>
<nav>
<label for='dismiss'>Dismiss</label>
</nav>
<iframe src='https://example.com' scrolling='no'></iframe>
</section>
</body>
</html>
tl;dr:不要在
iframe
内进行 DOM 操作,而是通过 window.parent.postMessage()
发送消息来告诉父窗口要做什么。
例如,在
localhost
上启动 Web 服务器,无论端口如何。
创建
opener.html
:
<h1>Parent Window</h1>
<script>
const iframe = document.createElement('iframe');
const url = new URL(document.location);
// Ensure that the opener and iframe have different origins. For
// security considerations, 'localhost' and '127.0.0.1' are not the
// same origin.
if (url.hostname === 'localhost') {
url.hostname = '127.0.0.1';
} else {
url.hostname = 'localhost';
}
url.pathname = '/iframe.html';
url.search = 'opener=' + encodeURIComponent(document.location.origin);
iframe.src = url.toString();
iframe.id = 'iframe';
document.body.appendChild(iframe);
window.addEventListener('message', event => {
if (event.origin === url.origin) {
if ('close' === event.data.type) {
iframe.remove();
}
}
});
</script>
现在创建
iframe.html
:
<h1>IFrame</h1>
<button id="close">Close</button>
<script>
document.getElementById('close').addEventListener('click', () => {
const parentWindow = window.parent;
if (parentWindow) {
const params = new URLSearchParams(document.location.search);
parentWindow.postMessage({ type: 'close' }, params.get('opener'));
}
});
</script>
打开http://localhost:8080/opener.html(根据您的设置更改端口)。现在可以通过单击
Close
按钮关闭 iframe。
工作原理:父窗口将其自己的原点作为 URL 参数
opener
传递给 iframe。
在 iframe 中的点击处理程序中,使用
opener
参数作为目标源向父级发送一条消息。
在父级的消息处理程序中,检查消息的源,然后从 DOM 中删除 iframe。同样,您可以调整 iframe 的大小、移动它、更改其颜色,甚至设置 cookie。