Firefox失败-使用文档后.写入和更新位置.哈希导致页面刷新

Firefox Fail - After using document.write and update to location.hash causes page refresh

本文关键字:哈希导 位置 更新 刷新 失败 文档 Firefox      更新时间:2023-09-26

下面是一些HTML (Fiddle):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Test Write</title>
<script>
    function test() {
        if (window.location.hash == '#test') {
            alert('The hash is already set!');
        } else {
            document.open();
            document.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
<html>'
<head>'
<title>Hello There!</title>'
<script>'
    function test() {'
        window.location.hash="test";'
    }'
</'+'script>'
</head>'
<body>'
    <button onclick="test()">Test Hash Now</button>'
</body>'
</html>');
            document.close();
        }
    }
</script>
</head>
<body>
    <button onclick="test()">Click to write new page</button>
</body>
</html>

如果你运行这个-然后点击"点击写新页面"-它会写一个新的HTML片段到文档。这次有一个按钮"Test Hash Now"-当你点击它所做的就是更新window.location.hash.

在FireFox中,页面试图再次意外地重新加载。在所有其他浏览器中,它工作得很好。在Fiddle中,你会看到一个错误消息{"error": "Please use POST request"},如果你创建一个HTML文件,它会工作得更好,你会看到"点击写新页面"按钮再次出现后,点击"现在测试哈希"这是(或应该是)错误的。

为什么会发生这种情况?

我的用例很简单-我有一个bootstrap页面,其中包含一个使用AJAX获取一堆数据的javascript。然后它生成一个大的HTML字符串(包括doctype/head/body/etc),然后它只需要渲染那个HTML字符串。

在这种情况下,我使用内联HTML作为常量-但在实际情况下,它是使用一些逻辑生成它。我正在尝试模拟服务器将响应的内容,并消除客户端的任何服务器端需求。

我只是有一堆HTML和JS文件压缩成一个文件,我可以给任何人(开发人员或不是)运行,而不需要任何服务器或数据库。然后他们就能看到那张纸了,就好像它是真的一样。这就是我的目标。如果我只是将HTML放入页面上的现有元素中(比如只是操作当前页面的主体),那么它的行为就不会与生成整个文档完全相同。另外,我希望引导的HTML文件是非常小的(只有一个javascript包含在顶部)。

一切似乎都可以工作-除了Firefox是唯一失败的。这一切都是有效的,除非有一个脚本引用的页面需要写一些东西到window.location.hash -然后它试图重新加载整个页面…Uggg…

有更好的方法来完成这个吗?

我试图创建一个iframe,并使用相同的document.open();document.write(html);document.close() -但同样的问题发生。

尝试以下代码推送哈希状态:

if (history.pushState) {
    history.pushState(null, null, '#test');
}
else {
    location.hash = '#test';
}

但是我自己还没有测试过。

添加:尝试将函数命名为test1()和test2()。这并不一定会修复它,但它可能有助于调试/发现正在发生的事情。