【问题标题】:YouTube not triggering history.pushStateYouTube 没有触发 history.pushState
【发布时间】:2015-05-12 18:54:40
【问题描述】:

我正在尝试使用 history.pushState 检测 YouTube 上的页面更改,但它似乎从未触发。我最终希望通过 Tampermonkey/Greasemonkey 脚本来实现这一点,为此我知道您需要将脚本注入到实际页面中,我已经这样做了,但无济于事:

html = 
    "var oldState      = history.pushState;"+
    "history.pushState = function() {" +
        "alert('url changed');" +
        "return oldState.apply(this);" +
    "}";

var head = document.getElementsByTagName("body")[0];         
var script = document.createElement('script');
script.type = 'text/javascript';
script.innerHTML = html;
head.appendChild(script);

我也尝试从调试控制台运行相同的代码:

var oldState      = history.pushState;
history.pushState = function() {
    alert('url changed');
    return oldState.apply(this);
};

但这似乎也没有用。有人知道这里发生了什么吗?

【问题讨论】:

  • 是什么让您认为history.pushState 会检测到变化?该方法添加到历史记录。 检测变化需要监听popstate事件。
  • 我正在重写该函数,或者至少是这样的想法。 onpopstate 似乎仅在按下后退和前进按钮时触发(根据我的测试)。见stackoverflow.com/a/4585031/1107110
  • 啊,好的。您是否首先检查过您的脚本插入是否真的有效?就像尝试在其中放置 console.log 语句一样,看看是否会产生预期的输出……
  • 是的,脚本插入没问题。
  • console.log(history.pushState)(在覆盖之前)会产生什么?

标签: javascript youtube html5-history


【解决方案1】:

YouTube 使用 spfjs 来操纵 pushState。但是,它通常会在您对其进行修补之前获取该功能。这就是您遇到此问题的原因。

要么在加载 spf.js 之前将你的猴子补丁脚本向上移动到页面中,要么你可以像 spfdone 一样查找spf events 来检测更改。

【讨论】:

  • @Rob 我正在尝试在 nw.js 预加载脚本 (inject_js_start) 中对其进行修补,这肯定早于 spfjs 加载。另外,我验证了该功能已成功修补。奇怪的是,它不会被 youtube(或 spfjs)调用。看起来它做了一些奇怪的事情(比如操纵历史而不称之为 pushState/replaceState) - 有什么想法吗?
  • @Martynas 我将事件用于我的脚本,而不是猴子补丁。但是已经有一段时间了,自从 Material 重新设计以来,我的大部分抱怨都得到了解决,所以我不需要 youtube 的用户脚本
  • 谢谢@Rob。我已经解决了这个问题 - 这是由于 youtube 使用来自“about:blank”iframe 的历史 API 而不是来自主窗口(但它仍然以某种方式影响主窗口的历史)。我不明白他们为什么这样做,或者为什么它似乎违反直觉。如果有人知道答案,请告诉我。哦,更令人困惑的是,它仍然加载具有历史操作但从未被调用的 spfjs 代码。
猜你喜欢
  • 2021-01-03
  • 2012-06-12
  • 2020-09-18
  • 2011-12-07
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
  • 2021-09-15
  • 2011-01-06
相关资源
最近更新 更多