每次在YouTube上加载新页面时如何运行脚本?

时间:2014-01-14 20:12:08

标签: javascript jquery html youtube greasemonkey

从去年的某个时候开始,YouTube就让每个页面实际上都没有加载一个全新的页面,但主要只是重新加载div#content中的内容。当您点击YouTube中的链接并看到页面顶部的红色加载栏时,您会注意到这一点。

我有一个Greasemonkey脚本修改了YouTube上的元素,但是现在YouTube没有重新加载整个页面,Greasemonkey脚本不再在每个“新”页面上触发。如何在我加载到YouTube上的每个“新”页面上激活Greasemonkey脚本?

我在这个Greasemonkey脚本中使用jQuery。我尝试使用.on()DOMNodeInserted之类的功能,但我找不到合适的组合以使其正常工作。使用我一直在使用的事件监听器,我最终会为每个页面加载运行我的脚本数百次,例如以下内容:

$('div#page').on('DOMNodeInserted', 'div#content', function() { });

我想到的另一个解决方案是在YouTube上加载所有链接,就像正常情况一样,没有他们正在做的新方式。

3 个答案:

答案 0 :(得分:6)

经过一些研究,我自己想通了。首先,我不喜欢使用setTimeout的解决方案。这通常是一种有利于被弃用的DOMNodeInserted的方法(我在我的一些脚本中使用,但尽量避免使用),但如果可能的话,我总是更喜欢脚本的解决方案实际上在特定事件之后执行。我已经发布了我最初在下面第一部分中使用的解决方案,然后是我在第二部分中使用的最终解决方案。 以下所有代码都需要jQuery。

体面的解决方案,但不是最好的

首先,我有一个解决方案,我向所有click元素添加了一个A事件,这将运行一个在2秒后运行我的脚本的计时器。这不是很优雅,因为如果页面加载很快,那么脚本没有运行会有一瞬间。如果页面加载超过两秒,那么脚本根本不会运行。下面的脚本:

$('a').click(function()
{
    setTimeout(youtubeFunction, 2000);
});

更好的解决方案

所以我开始寻找与我想要完成的事情相关的解决方案。我最终找到了其他与我有类似问题的人(例如想要创建修改YouTube页面的Chrome脚本的人)。这导致我this particular Stack Overflow solution,这基本上说YouTube页面顶部的红色加载栏是一个CSS过渡元素,并且它在完成时创建了一个transitionend(区分大小写)事件。链接解决方案中的代码并不完整(对我来说无论如何),但它确实解释了如何实现可行的解决方案。我每页只运行一次代码,这是完美的。所以这就是我现在所拥有的:

function youtubePageChange()
{
    youtubeFunction();
    $('body').on('transitionend', function(event)
    {
        if (event.target.id != 'progress') return false;
        youtubeFunction();
    });
}

$(youtubePageChange);

为了解释上面的代码,基本上我在第一次加载YouTube页面时运行一次代码(例如在地址栏中输入URL)。然后,对于每个需要进度条的后续点击,代码将再次运行。

红色进度条形码

哦,为了将来参考,当红色进度条出现在YouTube页面顶部时,该网站会临时在DIV的末尾添加一个新的BODY,其代码如下:< / p>

<div id="progress" class="waiting" style="transition-duration: 400ms; width: 99%;"><dt></dt><dd></dd></div>

答案 1 :(得分:0)

连接到popstate可能是一个选项,但由于某些原因我无法正常工作(youtube可能阻止它传播),所以我想出了这个概念:

var currentState = "";
setInterval(function(){
    if (currentState != history.state["spf-referer"]) {
        currentState = history.state["spf-referer"];
        console.log("Do Stuff!");
    }
},250)

只需观察history.state即可更改,此时它将记录。状态应该在URL更改时随时更改,即使它不是由于页面重新加载。

答案 2 :(得分:0)

您可以设置一个在页面加载完成后调用的侦听器。

这适用于新的YouTube资料设计:

body.addEventListener("yt-navigate-finish", function() {
    //your code
});

这是旧的:

window.addEventListener("spfdone", function() {
    //your code
});

(如果你使用*猴子,你需要使用unsafeWindow

请记住,旧设计将停止使用,因此您的脚本可能无法使用。