将html写入带回调的iframe中



我们从后端获取数据,需要将其写入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/

最新更新