【问题标题】:Is it possible to capture the window.location.replace event?是否可以捕获 window.location.replace 事件?
【发布时间】:2018-09-17 02:31:02
【问题描述】:

如果我当前位于 URL"example.com/somepage#somehash" 并调用 window.location.hash = "anotherhash",则 URL 将更改为 "example.com/somepage#anotherhash"。这会触发 window.hashashchange 事件。

如果我当前位于 URL "example.com/somepage?a=1&b=two" 并调用 window.location.replace("?one=1&two=2"),则 URL 将更改为 "example.com/somepage?one=1&two=2"

我已经阅读了MDN docs,但我找不到它会触发的内容。

  1. 有吗?
  2. 如果没有,有没有简单的方法来捕获该事件?

注意:

说我想确保不会触发页面重新加载是我的错。我想使用新 URL 根据查询字符串更新页面,例如使用 AJAX 请求。 window.history.pushState 是另一种选择,但据我所知,它也不会触发事件。

编辑

我看了@Taki 的回答。我创建了一个repl.it,因为当您转到全页视图时,您可以看到 URL 的变化。然而,即使使用preventDefault,页面仍在重新加载,这可以通过卸载事件回调中发布到页面的信息消失的事实来证明。因此,这不能用于客户端路由,这是我的目标。

index.html

<button id="myBtn">Click me</button>
<div id="info"></div>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="index.js"></script>

index.js

console.log("index.js");

$('#myBtn').on('click', function(e)
{
  console.log("button clicked")
  window.location.replace("?one=1&two=2")
  console.log(window.location.href);
});

$(window).on("beforeunload", function (event) 
{
  event.preventDefault(); // just to pause and see the cosdole
  console.log("beforeunload");
  console.log(event);
  $('#info').append("<p>beforeunload</p>");
  console.log(window.location.href); // capture the url
});

【问题讨论】:

    标签: javascript html dom-events hashchange


    【解决方案1】:

    window.location.replace 就像一个重定向,所以你可以监听BeforeUnload 事件

    Location.replace() 方法将当前资源替换为 一个在提供的网址

    (不知道为什么它不能替换 sn-p 中的window.location :P 但它会在它之外工作)

    document.querySelector('#myBtn').addEventListener('click', function(){
      window.location.replace("?one=1&two=2")
    });
    
    window.addEventListener("beforeunload", function (event) {
    
      console.log(window.location.href); // capture the url
      event.preventDefault(); // just to pause and see the condole
      
    });
    &lt;button id="myBtn"&gt;Click me&lt;/button&gt;

    编辑:

    显然您无法在更改 location.href 时阻止页面重新加载,但就像您提到的那样,您可以使用 history.pushState 如果它没有触发事件,请创建一个自定义事件,将其附加到窗口并听一听:

    let evt = new CustomEvent('myEvent', ...
    window.dispatchEvent(evt); 
    
    ... 
    
    window.addEventListener('myEvent', function(e){ ...
    

    这一次它在 sn-p 中工作,注意它没有重新加载,你可以将 url 保留在历史记录中,你会得到你的 location

    document.querySelectorAll('a').forEach(function(elem){
    		
      elem.addEventListener('click', function(e){
    			
        e.preventDefault();
        window.history.pushState("object or string", "Title", this.href);
    				
        let evt = new CustomEvent('urlChange');
        window.dispatchEvent(evt);
    				
      });
    			
    }); 
    
    window.addEventListener('urlChange', function(e){
      document.querySelector('#myUrl').innerHTML = window.location.href;
    });
    #myUrl{
      display: block;
      font-size: 20px;
      margin-top: 20px;
    }
    <h1>hello</h1>
    <a href="/one">Got to One</a><br />
    <a href="/two">Got to Two</a><br />
    <a href="?three=3">Got to Three</a><br />
    
    <span id="myUrl"></span>

    【讨论】:

    • 谢谢。我玩过这个,但我不确定它是否适合我,因为它会完全重新加载页面。
    • 但那是我的错,因为我没有说我想避免页面重新加载。更改哈希不会这样做。
    • 使用 pushState 并触发自定义 event ,检查编辑
    • 是的。那将是做到这一点的方法。尽管它不像另一个回调那样是一个自定义事件。这样我就不必乱来了,我只是要使用哈希而不是“?”对于查询。不那么传统,但代码更少。
    • 顺便说一句——这确实是一个简单自定义事件的好例子。我会再玩一些。
    【解决方案2】:

    不,不存在这样的事件,检测此类事件何时发生的最简单方法是围绕历史设置代理 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

    或者你可以重写它的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      • 2011-10-30
      • 2017-03-01
      • 2023-02-22
      相关资源
      最近更新 更多