Эта проблема возникает только в IE (по крайней мере, 8 и 9). После динамического добавления элемента в DOM содержимое встроенного iframe теряется при повторном входе на страницу с помощью клавиши BACK / FORWARD. Воспроизведите проблему всего два небольших файла HTML.
Первый файл - iframe.htm:
<!DOCTYPE html>
<html>
<head>
<title>IE iframe bug</title>
<script type="text/javascript">
function mytrace(msg) {
var t = document.createTextNode(msg);
var b = document.createElement('br');
var d = document.getElementById("trace_output")
d.appendChild(t);
d.appendChild(b); /// will work if commented
}
function submitListing() {
mytrace('submitListing()');
var doc = document.getElementById("output_iframe")
.contentWindow.document;
var d = new Date;
doc.location.replace('report.htm?invalidateCache=' + d.getTime());
//mytrace('submitListing(): out');
}
</script>
</head>
<body>
<div id="trace_output"><br /></div>
<input type="button" onclick="submitListing();" value="Run" /><br />
<iframe id="output_iframe" src=""></iframe>
</body>
</html>
Второй файл - report.htm:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<a href="http://google.com" target="_top">LINK</a>
</body>
</html>
Действия по воссозданию проблемы (НАЗАД): 1013 *
- Поместить вышеуказанное содержимое в два файла
- Просмотр файла iframe.htm
- Нажмите кнопку Run, чтобы загрузить report.htm в iframe
- Нажмите на ссылку LINK, чтобы загрузить другую страницу
- Нажмите кнопку НАЗАД браузера, чтобы вернуться на страницу с кэшем (lmao)
- содержимое iframe пропало !!!! (только в IE - safari, chrome, firefox сохраняют содержимое)
Также .. (ПРЯМОЙ КЛЮЧ)
- Просмотр произвольной страницы (для истории http://www.google.com работ)
- Загрузите iframe.htm в ту же вкладку
- Нажмите кнопку Run, чтобы загрузить report.htm в iframe
- Нажмите кнопку НАЗАД браузера, чтобы вернуться на первую страницу
- Нажмите кнопку браузера ВПЕРЕД, чтобы вернуться к iframe.htm
- содержимое iframe снова исчезло !!
Теперь закомментируйте строку:
d.appendChild(b)
Это одно изменение позволяет всем работать в IE. Тем не менее, мое решение должно выполнять такие виды DOM-манипуляций (тяжелое приложение jQuery / AJAX) и иметь возможность восстанавливать iframe через действия браузера BACK / FORWARD.
Похоже, мне придется запомнить содержимое iframe, чтобы я мог восстановить его при доступе к странице с помощью клавиш BACK / FORWARD. Я не в восторге от этого, потому что иногда содержание iframe будет довольно большим, и это может занять немного памяти и времени, чтобы сделать еще одну копию встроенного документа для восстановления. Я хотел бы услышать некоторые другие идеи о том, как я мог бы подойти к этому. Заранее спасибо.
EDIT
Следующая замена iframe.htm поможет обойти проблему с IE. Я собираюсь переписать это с помощью jQuery и добавить немного логики для восстановления позиций прокрутки. Я надеялся на что-то более элегантное, но это делает работу.
<!DOCTYPE html>
<html>
<head>
<title>IE iframe bug</title>
<script type="text/javascript">
function myTrace(msg) {
var t = document.createTextNode(msg);
var b = document.createElement('br');
var d = document.getElementById("trace_output")
d.appendChild(t);
d.appendChild(b);
}
var make_backup ="false";
function submitListing() {
make_backup = "true";
myTrace('submitListing()');
var doc = document.getElementById("output_iframe").contentWindow.document;
var d = new Date;
doc.location.replace('report.htm?invalidateCache=' + d.getTime());
//myTrace('submitListing(): out');
}
function iframe_load() {
myTrace("iframe loaded, is_cached=" + document.getElementById("is_cached").value);
if (make_backup == "true") { // only when submitting
var htm, doc;
make_backup = "false"
doc = document.getElementById("output_iframe").contentWindow.document;
htm = doc.documentElement.innerHTML;
document.getElementById("iframe_backup").value = htmlEscape(htm);
}
}
function bodyLoaded() {
var is_cached = document.getElementById("is_cached");
if (is_cached.value == "false") { // initial page load
is_cached.value = "true";
}
else { // BACK or FORWARD, restore DOM where needed
var htm;
htm = htmlUnescape(document.getElementById("iframe_backup").value);
var doc;
doc = document.getElementById("output_iframe").contentWindow.document;
doc.open();
doc.writeln(htm);
doc.close();
}
}
function htmlEscape(str) {
return String(str).replace(/&/g, '&').replace(/"/g, '"')
.replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
}
function htmlUnescape(str) {
return String(str).replace(/&/g,'&').replace(/"/g,'"')
.replace(/'/g,"'").replace(/</g,'<').replace(/>/g,'>');
}
</script>
</head>
<body onload="bodyLoaded();">
<div id="trace_output" style="height: 300px; border-width:1; background-color: Silver"><br></div>
<input id="is_cached" type="hidden" value="false">
<input id="iframe_backup" type="hidden">
<input type="button" onclick="submitListing();" value="Run"><br>
<iframe id="output_iframe" src="" onload="iframe_load();"></iframe>
</body>
</html>
РЕДАКТИРОВАТЬ 2
Переписано с помощью jQuery:
<!DOCTYPE html>
<html>
<head>
<title>IE iframe workaround2</title>
<script type="text/javascript" src="Scripts/jquery-1.7.1.js"></script>
<script type="text/javascript">
var make_backup = "false";
$(document).ready(function () {
myTrace('document ready()');
var is_cached = $("#is_cached");
if (is_cached.val() == "false") { // initial page load
is_cached.val("true");
}
else { // BACK or FORWARD, restore DOM where needed
if ($.browser.msie) { // IE loses iframe content; restore
var htm = htmlUnescape($("#iframe_backup").val());
var doc = $("#output_iframe")[0].contentWindow.document;
doc.open();
doc.writeln(htm);
doc.close();
myTrace('iframe contents restored');
}
}
$('#output_iframe').load(function () {
myTrace("iframe_loaded");
if (make_backup == "true") { // only when submitting
make_backup = "false"
if ($.browser.msie) {
var doc = $("#output_iframe")[0].contentWindow.document;
var htm = doc.documentElement.innerHTML;
$("#iframe_backup").val(htmlEscape(htm));
myTrace('iframe contents backed up');
}
}
});
$('#submit_listing').click(function () {
make_backup = "true";
myTrace('submitListing()');
var doc = $("#output_iframe")[0].contentWindow.document;
var d = new Date;
doc.location.replace('report.htm?invalidateCache='+d.getTime());
});
});
function myTrace(msg) {
$('#trace_output').append(msg + '<br>');
}
function htmlEscape(str) {
return String(str).replace(/&/g, '&').replace(/"/g, '"')
.replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
}
function htmlUnescape(str) {
return String(str).replace(/&/g,'&').replace(/"/g,'"')
.replace(/'/g,"'").replace(/</g,'<').replace(/>/g,'>');
}
</script>
</head>
<body>
<div id="trace_output"
style="height: 300px; border-width:1; background-color: Silver">
<br></div>
<div style="display: block;">
<input id="is_cached" type="text" value="false">
<input id="iframe_backup" type="text" type="hidden"></div>
<input id="submit_listing" type="button" value="Run"><br>
<iframe id="output_iframe" src=""></iframe>
</body>
</html>