Как создать кросс-браузерный документ с iframe или shadow dom?
Я хочу создать полностью инкапсулированный поддокумент в JavaScript с его собственными <head>
, <body>
, стилями, html и js. В основном теневое dom или iframe, но без атрибута src.
Хотя мне нравится идея теневого домика, поддержка очень низкая, и, следовательно, не готова к прайм-тайм.
Итак, я работаю над созданием iframe, но на этом пути побывал целый ряд дорожных блоков. Вот jsFiddle, демонстрирующий мои различные попытки.
IFrame не может существовать в dom. Эта часть имеет решающее значение. Чтобы прояснить, это нормально, если оно на мгновение существует в dom, но оно должно быть доступно и доступно только в JS.
$('body').append('<iframe id="iframeGenerator" />');
var iframe3 = $('#iframeGenerator');
var iframe3Contents = iframe3.contents();
$('#iframeGenerator').remove();
var head = iframe3.contents().find('head');
сладкий, у нас есть голова
console.log(head.length);
но как выглядит содержимое?
console.log(iframe3Contents.get(0));
Это документ, но не внутри элемента
поэтому попробуем поместить его в дом или внутри другого элемента?
обе следующие попытки не работают, потому что селектор не имеет контекста или чего-то еще...
$('body').append(iframe3Contents);
var generatedIframe = $('<iframe />').append(iframe3Contents);
Я хотел бы иметь возможность создавать iframe/subdocuemnt, не добавляя ничего в dom... но если я должен, я все равно хотел бы, чтобы впоследствии удалить его из dom и управлять им дальше в js.
У меня есть эта небольшая функция, которая не работает, но иллюстрирует тип генератора iframe или subdocument, который я хотел бы создать
var iframeHtml;
giveMeIframe = function() {
var iframeContents;
if (iframeHtml) {
return iframeHtml;
} else {
$('body').append('<iframe id="iframeGenerator" style="display: none" />');
iframeContents = $('#iframeGenerator').contents();
iframeHtml = $('<iframe />');
iframeHtml.append(iframeContents);
$('#iframeGenerator').remove();
return iframeHtml;
}
}
Ответы
Ответ 1
Чтобы получить доступ к информации из фрейма (или записать в кадр), он должен находиться в DOM. Он может быть скрыт, но он все равно должен жить в объекте frames. JQuery обращается к iFrame через объект frames и при удалении из dom он удаляется из объекта frames
В будущем обратитесь к любому, кто споткнется по этому вопросу, вы можете получить инкапсуляцию следующим образом:
$('#iframeGenerator2').contents().find('html').html(frame2HTML);
Вот пример: http://jsfiddle.net/yP34y/4/
В примере jsfiddle обратите внимание, что все работает только после его добавления в DOM.
Ответ 2
Я играл со своей скрипкой и смог заставить ее работать. Я использую бесшовную (только Chrome), чтобы заставить ее вести себя в соответствии с тем, что вы ищете, и у меня есть резерв CSS для других браузеров.
Как примечание, iframe необходимо добавить в DOM, прежде чем вы начнете редактировать его содержимое (добавив стили и тело). Вы можете удалить потом document.body.removeChild(iframe);
.
До сих пор существует много возможностей, чтобы заставить его вести себя очень похоже на элемент DOM для тени, эта презентация поможет вам Бесшовные фреймы: будущее, сегодня!
JS
var styles = '<style> .pink { color: pink; width: 100px; height: 100px; } body{background-color:#eee;}</style>';
var html = '<div class="pink">PINK!</div>';
// create iframe
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
//add head and body
iframe.contentDocument.open();
iframe.contentDocument.write(styles);
iframe.contentDocument.write(html);
iframe.contentDocument.close();
iframe.setAttribute('seamless', 'seamless');
//check everything
console.log(iframe);
var head = $(iframe).contents().find('head')[0];
console.log(head);
var body = $(iframe).contents().find('body')[0];
console.log(body);
//remove from DOM
//document.body.removeChild(iframe);
CSS
iframe[seamless]{
background-color: transparent;
border: 0px none transparent;
padding: 0px;
overflow: hidden;
}