Создание iframe с заданным HTML динамически
Я пытаюсь создать iframe из JavaScript и заполнить его произвольным HTML, например:
var html = '<body>Foo</body>';
var iframe = document.createElement('iframe');
iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html);
Я бы ожидал iframe чтобы затем содержать допустимое окно и документ. Однако, это не так:
консоли>.журнал(фрейма.contentWindow);
null
попробуйте сами:http://jsfiddle.net/TrevorBurnham/9k9Pe/
что я упускаю из виду?
4 ответов:
задание
srcсозданногоiframeв javascript не запускает синтаксический анализатор HTML, пока элемент не будет вставлен в документ. Затем HTML обновляется, и синтаксический анализатор HTML будет вызван и обработает атрибут, как ожидалось.var iframe = document.createElement('iframe'); var html = '<body>Foo</body>'; iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html); document.body.appendChild(iframe); console.log('iframe.contentWindow =', iframe.contentWindow);также этот ответ на ваш вопрос важно отметить, что этот подход имеет проблемы совместимости с некоторыми браузерами, см. ответ @mschr для кросс-браузерное решение.
все же ваш
src = encodeURIдолжно работать, я бы пошел другим путем:var iframe = document.createElement('iframe'); var html = '<body>Foo</body>'; document.body.appendChild(iframe); iframe.contentWindow.document.open(); iframe.contentWindow.document.write(html); iframe.contentWindow.document.close();поскольку это не имеет ограничений x-домена и полностью выполняется через
iframeручка, вы можете получить доступ и манипулировать содержимым кадра позже. Все, что вам нужно сделать, это убедиться, что содержимое было визуализировано, которое будет (в зависимости от типа браузера) запускаться во время/после .команда записи - но не обязательно делать, когдаclose()is называемый.100% совместимый способ выполнения обратного вызова может быть такой подход:
<html><body onload="parent.myCallbackFunc(this.window)"></body></html>Iframes имеет событие onload, однако. Вот подход к доступу к внутреннему html как DOM (js):
iframe.onload = function() { var div=iframe.contentWindow.document.getElementById('mydiv'); };
Спасибо за ваш большой вопрос, это поймало меня несколько раз. При использовании источника HTML dataURI я нахожу, что мне нужно определить полный документ HTML.
см. ниже измененный пример.
var html = '<html><head></head><body>Foo</body></html>'; var iframe = document.createElement('iframe'); iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html);обратите внимание на содержимое html, завернутое с
<html>теги и тегiframe.srcстроку.элемент iframe должен быть добавлен в дерево DOM для анализа.
document.body.appendChild(iframe);вы не сможете проверить
iframe.contentDocumentесли выdisable-web-securityна вашем браузере. Вы получите сообщениеDOMException: не удалось прочитать свойство 'contentDocument' из 'HTMLIFrameElement': заблокирован кадр с источником"http://localhost:7357 " от доступа к кадру перекрестного происхождения.
существует альтернатива для создания iframe, содержимое которого представляет собой строку HTML:атрибут srcdoc. Это не поддерживается в старых браузерах (главный из них:Internet Explorer и, возможно, Safari?), но есть полифилл для этого поведения, которое вы могли бы поместить в условные комментарии для IE, или использовать что-то вроде has.js для условно ленивой загрузки.
Comments