Índice
fundo
No desenvolvimento diário, encontraremos uma situação em que a página precisa aninhar o iframe. Como o iframe não pode se adaptar à altura do estilo interno, precisamos monitorar a altura dinâmica do iframe
Método para realizar
Ideias de implementação
- Definir o observador MutationObserver
- Ouça o evento DOMContentLoaded do contentWindow do iframe (quando o documento HTML inicial é totalmente carregado e analisado)
- Quando o contentWindow.document.readyState do iframe for interativo (representando que o documento foi analisado, os recursos de estilo estão sendo carregados, etc.) inicie o monitoramento observer.observe(iframeEle.contentWindow.document, opções);
- O dom dentro do iframe é atualizado dinamicamente e o observador captura a alteração do dom. Nesse momento, você pode obter o contentWindow.document.body.scrollHeight e atribuir a altura ao elemento externo do iframe
Código de implementação
Não há muito a dizer, basta ir ao código
O iframe que precisa ser monitorado
<iframe id="iframeId" src="xxxxx"></iframe>
let iframeEle = document.getElementById('iframeId');
// 配置监听方法的属性值
const options = {
"childList" : true,
"attributes" : false,
"characterData" : false,
"subtree" : true,
"attributeOldValue" : false,
"characterDataOldValue" : false
};
// 定义一个监听器
var observer = new MutationObserver((mutations) => {
let is_dom_change = false;
mutations.forEach((item) => {
if (item.type === 'childList') {
is_dom_change = true;
}
});
const scrollHeight = iframeEle.contentWindow.document.body.scrollHeight;
if (is_dom_change) {
iframeEle.style.height = `${scrollHeight}px`;
}
});
iframeEle.contentWindow.addEventListener('DOMContentLoaded', function(e) {
try {
if (iframeEle.contentWindow.document.readyState === "interactive") {
// 传入监听的dom,以及配置
observer.observe(iframeEle.contentWindow.document, options);
}
} catch (err) {}
});
cena estendida
Quando o link interno do iframe muda, ou o back-end ou gateway redireciona a página, como obter o último href no iframe?
Alguém pode dizer para usar o método onload, por exemplo
<iframe onload="handleOnload" id="iframeId"></iframe>
<script>
handleOnload(e) {
console.log('触发了onload事件');
}
</script>
Mas, no uso real, você descobrirá que o evento onload do iframe será acionado apenas uma vez em algum momento específico.
Para isso, podemos monitorar o método de carregamento do iframe e iniciar o monitoramento após o iframe ser carregado pela primeira vez para garantir a robustez do código
let iframeId = document.getElementById("iframeId")
iframeEle.contentWindow.addEventListener('DOMContentLoaded', function(e) {
try {
if (iframeEle.contentWindow.document.readyState === "interactive") {
iframeId.addEventListener("load", function(e) {
// 拿到iframe内部最新的href
console.log(iframe.contentWindow.location.href)
});
}
} catch (err) {}
});
documentos de referência
" DOMContentLoaded - Referência da interface da API da Web | MDN "
《document.readyState - referência da interface da API da Web | MDN》
" MutationObserver - Referência da interface da API da Web | MDN "