更改文档时窗口事件会发生什么?

14

嘿,我在窗口上设置了以下statechange事件:

History.Adapter.bind(window,'statechange',function(e){ 
 console.log("statechange event occured ");
 //more code
    var newDoc = document.open();
    newDoc.write(file);
    newDoc.close();
});

我正在使用 history.js,但在这种情况下它并不重要,因为它会定期绑定 statechange 事件,我获取了 file 的值并且运作良好。

现在我有这段代码(和其他代码)在一个外部 js 文件中,在文件内部我正在遍历所有的 a 标签并应用以下点击事件:

    $(element).on("click",function(e){
    e.preventDefault();
    //more code

    History.pushState({file : file},title, fullHref);


});

现在当我点击文档时,它会按预期更改,但是尝试使用后退/前进按钮时,statechange事件不会触发。

我应该提到,这个js也包含在我加载的文件中。

因此,我的初始想法是,随着文档的更改,但窗口没有更改,事件仍然存在。但事实并非如此,因为它多次应用statechange事件。所以我尝试使用Cookie只应用一次事件,但是还是会出现相同的问题。

现在,如果我不是更改文档,而是使用jQuery的.html(),则statechange事件将按预期触发,因此我认为与文档有关。

为什么会发生这种情况?我认为如果我更了解更改文档时窗口事件发生了什么,我就可以解决这个问题。

尝试:

  • 我现在也尝试通过常规历史记录API绑定到popstate事件,结果大致相同。pushState不会触发popstate,但返回按钮会触发,但没有状态。
  • 我得出结论,我不应该使用history.js,因为我怀疑问题来自那里,所以我通过popstate "解决"了我的问题,但文档打开似乎会触发popstate。仍在寻找更多信息
  • 我尝试使用on,结果相同

信息:

  • 此示例使用History是因为history.js,如果我使用常规历史记录API,仍然会出现相同的问题。

我在mdn中读到:

  
    

{{ gecko_minversion_note("1.9.2", "Starting with Gecko 1.9.2, document.open() uses the

  
     

principal of the document whose URI it uses, instead of fetching the   principal off the stack. As a result, you can no longer call   document.write() into an untrusted document from chrome, even using   wrappedJSObject.") }}

我不确定,但我认为可能与这个问题有关。

4个回答

2

最终,我发现即使您只更改文档,窗口事件也会被删除,因为它们位于文档内部。

我认为我在使用History.js时遇到了问题,因为我更改文档导致其在某些时候崩溃。

我的解决方法是使用本机HTML5历史记录API并在新文档中重新绑定popstate事件。


0

你尝试过使用LIVE绑定元素吗?

$(element).click(function(e){
    e.preventDefault();
    //more code
    History.pushState({file : file},title, fullHref);
});

变成

$(element).live('click',function(e){
        e.preventDefault();
        //more code
        History.pushState({file : file},title, fullHref);
    });

2
现在不再使用live,你应该使用on。是的,我试过了,但没有帮助。使用click只是我的一种尝试。 - eric.itzhak

0

你需要使用iframe来加载你的文档,并且可以轻松地更改它的文档。然后,你可以像这样监听点击事件:

$("#iframe").load(function () {
    $(this.contentWindow).click(function () {
        // do your click events here
    });
});

如果您更改src属性值为另一个文档,则iframe将重新加载。


我不必使用iframe,也不能使用iframe。当我使用document.open()时,我的点击事件确实发生了。 - eric.itzhak

0

1
w3schools网站上的信息不可靠,其他像MDN这样的网站也没有提到这些属性。 - eric.itzhak
你尝试过在点击时追踪 History 对象,以便查看该对象是否与根级别的 History 对象相同吗? - Gerrit Bertier
没有,但这已经不重要了,最终我解决了问题,感谢你的帮助! - eric.itzhak
我认为历史对象在覆盖文档时会被丢弃,因为它可能附加到DOM上,而本地历史API可能绑定得更高... 很高兴看到你找到了解决方法。 - Gerrit Bertier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接