设置 dom 的 innerHTML 后页面无响应

Page not responsive after setting innerHTML of dom

我正在创建一个要打印特定 div 的页面。我正在使用以下代码 (see also this post)

var printContents = document.querySelector('.mx-name-PrintArea').innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
window.reload();

在基础上,这就像一个魅力。我可以打印选定的 div。但是,当我return转到原来的页面时,我运行就出问题了。该页面看起来相同,但不再响应。例如,我的按钮不再起作用。脚本似乎不再有效。

有人知道怎么解决吗?

首先,这根本不是您处理使页面可打印的方式。相反,如果页面具有单独的查看和打印内容,则将页面的查看内容放在具有非 print 媒体查询的容器中,并将可打印内容放在具有 print 媒体的容器中询问。更多关于媒体查询 here.

CSS:

@media not print {
    .printing-container {
        display: none;
    }
}
@media print {
    .viewing-container {
        display: none;
    }
}

HTML:

<body>
    <div class="viewing-container">
    Content just for viewing here
    </div>
    <div class="printing-container">
    Content just for printing here
    </div>
</body>

那就是如果你想拥有完全独立的内容。否则,使用更具体的查询仅 hide/show 页面的各个部分。


但是对于您当前正在做的事情,问题是您正在破坏并重新创建 HTML 字符串中的元素,因此事件处理程序会丢失(以及其他一些状态信息)。

相反,将元素移动到 document fragment,然后在完成后返回到 body。例如:

将它们移动到片段中:

const frag = document.createDocumentFragment();
while (document.body.firstChild) {
    frag.appendChild(document.body.firstChild); // Moves it
}

将它们移回:

document.body.innerHTML = "";
while (frag.firstChild) {
    document.body.appendChild(frag.firstChild); // Moves it
}

因为它们是相同的元素,所以它们仍然会有自己的事件处理程序等。

实例:

// Initial page setup with an event handler
document.getElementById("btn-example").addEventListener("click", function() {
    console.log("Example button clicked");
    const frag = saveContents(document.body);
    document.body.innerHTML = "<p>This is the temporary DOM content</p>";
    setTimeout(() => restoreContents(document.body, frag), 1000);
});

function moveContents(from, to) {
    while (from.firstChild) {
        to.appendChild(from.firstChild);
    }
}

function saveContents(element) {
    const frag = document.createDocumentFragment();
    moveContents(element, frag);
    return frag;
}

function restoreContents(element, frag) {
    element.innerHTML = "";
    moveContents(frag, element);
}
<p>This is the original viewing content</p>
<input type="button" id="btn-example" value="Click Me">