我们从后端获取数据,需要将其写入iframe
。我们必须将iframe
高度设置为内容的高度。我们无法获得正确的高度,直到内容实际上在iframe
中,这对于大量内容而言并非瞬时。是否有回调要知道写入何时完成?
现在,我们有一个计时器,但这是脆弱的代码:
//data received from backend
//write data to iframe
//$iframe is a jQuery DOM element
$iframe[0].contentDocument.open();
$iframe[0].contentDocument.write(data);
$iframe[0].contentDocument.close();
setTimeout(function (){
var scrollHeight = $iframe.contents().find('body')[0].scrollHeight
$iframe.css("height", scrollHeight );
}, 1000);
您是否尝试过在iframe
上聆听load
事件?
var doc = $iframe[0].contentDocument
doc.open()
doc.write(data)
doc.close()
$iframe.on('load', function () {
this.style.height = doc.body.scrollHeight + 'px'
})
iframes确实有一个on load事件:
$iframe[0].contentDocument.open();
$iframe[0].contentDocument.write(data);
$iframe[0].contentDocument.close();
$iframe.onload = function() {
var scrollHeight = $iframe.contents().find('body')[0].scrollHeight
$iframe.css("height", scrollHeight);
};
您的最佳选择是在iframe中使用MutationObserver。恐怕这不像回调那样简单。
这是iframe-resizer库用来解决此问题的代码。您需要更改调用sendSize
的行以调用您的回调方法。
function setupBodyMutationObserver(){
function addImageLoadListners(mutation) {
function addImageLoadListener(element){
if (false === element.complete) {
console.log('Attach listeners to ' + element.src);
element.addEventListener('load', imageLoaded, false);
element.addEventListener('error', imageError, false);
elements.push(element);
}
}
if (mutation.type === 'attributes' && mutation.attributeName === 'src'){
addImageLoadListener(mutation.target);
} else if (mutation.type === 'childList'){
Array.prototype.forEach.call(
mutation.target.querySelectorAll('img'),
addImageLoadListener
);
}
}
function removeFromArray(element){
elements.splice(elements.indexOf(element),1);
}
function removeImageLoadListener(element){
console.log('Remove listeners from ' + element.src);
element.removeEventListener('load', imageLoaded, false);
element.removeEventListener('error', imageError, false);
removeFromArray(element);
}
function imageEventTriggered(event,type,typeDesc){
removeImageLoadListener(event.target);
sendSize(type, typeDesc + ': ' + event.target.src, undefined, undefined);
}
function imageLoaded(event) {
imageEventTriggered(event,'imageLoad','Image loaded');
}
function imageError(event) {
imageEventTriggered(event,'imageLoadFailed','Image load failed');
}
function mutationObserved(mutations) {
sendSize('mutationObserver','mutationObserver: ' + mutations[0].target + ' ' + mutations[0].type);
//Deal with WebKit asyncing image loading when tags are injected into the page
mutations.forEach(addImageLoadListners);
}
function createMutationObserver(){
var
target = document.querySelector('body'),
config = {
attributes : true,
attributeOldValue : false,
characterData : true,
characterDataOldValue : false,
childList : true,
subtree : true
};
observer = new MutationObserver(mutationObserved);
console.log('Create body MutationObserver');
observer.observe(target, config);
return observer;
}
var
elements = [],
MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
observer = createMutationObserver();
return {
disconnect: function (){
if ('disconnect' in observer){
console.log('Disconnect body MutationObserver');
observer.disconnect();
elements.forEach(removeImageLoadListener);
}
}
};
}
也许邮政事间会帮助您。
var testData = 'testntestntestntestntestntestntestntestntestntestntestntestn';
var $iframe = document.querySelector('#test-iframe');
var $button = document.querySelector('button');
// listen the callback message from iframe
window.self.addEventListener('message', function(ev) {
if (ev.data && ev.data.status === 'ready') {
$iframe.style.height = ev.data.height + 'px';
}
});
$button.addEventListener('click', function() {
// render content
$iframe.contentDocument.body.innerText = testData;
// send message to the top window
window.self.postMessage({
status: 'ready',
height: $iframe.contentDocument.body.scrollHeight
}, '*');
});
`
https://jsfiddle.net/caoyy/lb5k13bw/2/