凌海市 永新县 天台县 柯坪县 会同县 扎鲁特旗 什邡市 甘肃省 湖北省 丰原市 黄山市 鹿邑县 蓝田县 洛川县 丹寨县 米易县

那一场呼啸而过的青春_对于单页应用中如何监听 URL 变化的思考

标签:不识闲儿 手机版牛叉棋牌游戏

周末开发了一个在 GitHub 中给 repo 增加自定义备注的 chro天使之翼_2018年最新新闻网me 扩展。

开发这个扩展的原因是我在 GitHub 中所 star 的项目实在太多了(截止目前 671 个),有的项目过个几天回来看就忘了为什么 star 了,有的轮子想找的时候发现忘记叫什么了,这么多一个个找实在浪费时间。于是我一直在想有这么个工具,可以自定义对 GitHub 中的项目进行备注,然后可以根据备注进行搜索,于是便有了这个扩展。

如需安装体验请点击 GitHub Remarks 进行安装,源码移步 github-remarks

当然本文并不是讲这个扩展的制作过程,而是在这过程中碰到的一个问题。

以我的 GitHub 账户举例,在 https://githu杨澜访谈录_2018年最新新闻网b.com/hanzichi?tab=stars 页面,我需要插入一些 dom,使得页面如下:

乍一想,似乎很简单,在这个页面插入 content.js 就行,在 manifest.json 中增加配置:

{
  "matches": ["*://github.com/.*tabs=stars"],
  "js": ["content-scripts/repoDetail.js"],
  "css": [],
  "run_at": "document_end"
 }

但是问题来了,直接打开页面 https://github.com/hanzichi?tab=stars 并没有问题,但是如果从 https://github.com/hanzichi 点击跳转到 https://github.com/hanzichi?tab=stars,因为 GitHub 用了 pjax 技术,content.js 其实应该加载在页面 https://github.com/hanzichi 的,但是那个页面并没有参照的 dom 结构(好把我们需要的 dom 插入)。所以问题似乎就转为了,在 pjax 页面,如何能够监听到页面 url 的变化

首先一个很简单的方案是,弄个定时器循环监听,但是太耗费性能了,pass

因为页面是 pjax 跳转,所以 hashchange 这样的事件自然也用不上;而 pushstate 事件是监听浏览器前进后退的,所以也并不符合场景

有个想法很好,重写 pushState 事件(代码来自 How to detect when HTML5"s history.pushState() is called?):

(function(history){
    var pushState = history.pushState;
    history.pushState = function(state) {
        if (typeof history.onpushstate == "function") {
            history.onpushstate({state: state});
        }
        // ...罪恶王冠_2018年最新新闻网 whatever else you want to do
        // maybe call onhashchange e.handler
        return pushState.apply(history, arguments);
    }
})(window.history);

但是因为 chrome 扩展和源代码之间并不共享作用域,所以重写的 history.pushState 方法在原来页面其实并没有改变,所以也没什么卵用

然后从 chrome A遮天_2018年最新新闻网PI 入手,发现有个 chrome API 可以检测当前 url 改变的 tab(参考 Chrome extension WebNavigation listener for hash change):

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
  if (changeInfo.url) {
      console.log("Tab %d got new URL: %s", tabId, changeInfo.url)
  }
})

这段代码是在 background.js 中,然后一旦侦测到 URL 变化,background.js 和 content.js 通信告知即可。

但是,但是,也有问题,url 一改变确实能监听到,但是 chrome 扩展需要在相应 dom ready 后才能作用(才能在之前 dom 的基础上插入新的 dom),你无法检测到什么时候 dom 已经准备就绪了,所以在这里加个定时器延迟作用是可行的,时间需要自己估算下

这个方法不是很优雅,最后想到,pjax 的过程中,dom 肯定有变化,所以监听 dom 变化是否可行?答案是可以的:

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var observer = new MutationObserver(function(mutations, observer) {
  let url = location.href 
  let p = /.*//github.com/.*?tab=stars.*/

  if (p.test(url)) {
    initStarsPage()
  }
})

observer.observe(document.getElementById("js-pjax-container"), {
  childList: true
})

$(document).ready(() => {
  let url = location.href 
  let p = /.*//github.com/.*?tab=stars.*/

  if (p.test(url)) {
    initStarsPage()
  }
})

写到最后,其实并不是监听了 URL,而是监听了 dom 的变化。

最后的最后,意外在 so 上找到 这个答案 似乎就是对应我的问题,大概看了下,除了我举例的几个方案外,其实我遗漏了最简单的一个方案,既然页面使用了 pjax,那么直接监听 pjax:complete 事件即可:

$(d我们说好的_2018年最新新闻网ocument).on("pjax:complete", function() {
  let url = location.href 
  let p = /.*//github.com/.*?tab=stars.*/

  if (p.test(url)) {
    initStarsPage()
  }
})

突然让人感觉,有时候 "真相" 往往总是那么简单。比亚迪_2018年最新新闻网

当前文章:http://t4ztbf27p-fendoubei-com.kuicomputing.cn/ujv/0ef09_154984.html

发布时间:2019-10-14 00:33:55

2949.com澳门银河娱乐  澳门银河www66356com  银河娱乐在线官方网址  澳门银河2949所有网址  银河国际手机网址2949停车杆砸人致死 家属索赔161万元  澳门银河送彩金罗晋拍打戏拒用替身:受不了动作戏不真实  澳门银河送彩金  919银河优越会  银河国际手机网址2949停车杆砸人致死 家属索赔161万元  西藏双湖县发生4.6级地震 震源深度5千米  

用手机访问
下载APP
appicon 下载
扫一扫,手机浏览
code
休闲娱乐
综合热点资讯
单机游戏下载

精彩专栏
游民星空联运游戏