如何监听URL参数变化?,实现伪SPA单页面应用

在老的jqury项目中通常实现SPA一般都采用hash值变化来进行监听,但是有的项目中我们也想采用改变URL参数来进行监听,一般我们使用window.history.pushState方法来改变url参数;

为了在使用 window.history.pushStatewindow.history.replaceState 后能够检测到浏览器的后退按钮操作,可以通过监听 popstate 事件来处理浏览器导航历史变化。popstate 事件在用户点击浏览器的后退或前进按钮时触发。

说明:
1、监听浏览器地址URL的参数变化;
2、点击浏览器前进和后退按钮的时候也可触发监听事件;

 

下面是示例代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button onclick="changeUrl()">改变URL参数</button>

    <script>
      /**
       * 改变url参数
       * 随便找个简单的例子2个参数p1和p2
       * */
      function changeUrl() {
        let random = Math.floor(Math.random() * 100);
        let newP = `p1=${random}&p2=${random * 2}`;
        updateUrlWithNewParams(newP);
      }

      // 注册修改 pushState 和 replaceState 以触发自定义事件
      (function (history) {
        const pushState = history.pushState;
        const replaceState = history.replaceState;

        history.pushState = function (state, title, url) {
          const result = pushState.apply(history, arguments);
          const urlChangeEvent = new Event(urlChangeEventType);
          window.dispatchEvent(urlChangeEvent);
          return result;
        };

        history.replaceState = function (state, title, url) {
          const result = replaceState.apply(history, arguments);
          const urlChangeEvent = new Event(urlChangeEventType);
          window.dispatchEvent(urlChangeEvent);
          return result;
        };
      })(window.history);
      // 自定义事件类型
      const urlChangeEventType = "urlChange";
      // 监听 popstate 事件以处理浏览器后退和前进操作
      window.addEventListener("popstate", function (event) {
        const urlChangeEvent = new Event(urlChangeEventType);
        window.dispatchEvent(urlChangeEvent);
      });
      // 监听自定义的 URL 变化事件
      window.addEventListener(urlChangeEventType, function (event) {
        // 在这里处理 URL 变化后的逻辑
        pageInit();
      });
      // 更新url参数
      function updateUrlWithNewParams(newParams) {
        // 获取当前URL
        let url = window.location.href;
        let baseUrl = url.split("?")[0]; // 基础URL
        let newParamsObj = new URLSearchParams(newParams); // 新的参数对象

        // 构造新的URL
        let newUrl = `${baseUrl}?${newParamsObj.toString()}`;

        // 使用history.pushState更新URL,不重新加载页面
        window.history.pushState({ path: newUrl }, "", newUrl);
      }

      function getUrlParams(url = window.location.href) {
        const params = {};
        // 使用 URL 构造函数解析 URL
        const urlObj = new URL(url);
        // 获取查询字符串
        const queryString = urlObj.search;
        // 使用 URLSearchParams 解析查询字符串
        const urlSearchParams = new URLSearchParams(queryString);

        // 遍历所有参数并添加到对象
        for (const [key, value] of urlSearchParams.entries()) {
          params[key] = value;
        }

        return params;
      }

      function pageInit() {
        alert("修改url了");
        console.log("新参数", getUrlParams());
      }
    </script>
  </body>
</html>

 

posted @ 2024-05-30 16:19  bbliang  阅读(549)  评论(0)    收藏  举报