每次在YouTube上加载新页面时如何运行脚本? [英] How to run a script every time a new page is loaded on YouTube?

查看:221
本文介绍了每次在YouTube上加载新页面时如何运行脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

去年的一段时间以来,YouTube让每个页面都没有真正加载一个全新的页面,但主要是重新加载 div#content 。当您点击YouTube中的链接并看到页面顶部的红色加载栏时,您可以注意到这一点。

我有一个Greasemonkey脚本,用于修改YouTube上的元素,但现在YouTube无法重新加载整个页面,Greasemonkey脚本不再在每个新页面上触发。我如何使Greasemonkey脚本在我加载到YouTube上的每个新页面触发?



我在这个Greasemonkey脚本中使用jQuery。我尝试使用 .on() DOMNodeInserted 之类的函数,但是我找不到合适的组合来使它工作正常。使用我一直使用的事件监听器,每次页面加载后,我最终都会运行脚本数百次,如下所示:

<$ c $ ('DOMNodeInserted','div#content',function(){});



我想到的另一个解决方案是在YouTube上加载页面上的所有链接,就像普通网页一样,没有新的方式,他们正在做这件事。

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

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



起初,我有一个解决方案,我在所有 A 元素中添加了一个 click 事件,它会运行一个计时器2秒后运行我的脚本。这并不优雅,因为如果页面加载速度很快,那么脚本没有运行的时间就会有一秒钟。如果页面加载超过两秒钟,那么该脚本根本不运行。脚本如下:

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



更好的解决方案



寻找与我想要完成的事情有关的解决方案。我最终发现了与我类似的其他人(例如,希望创建修改YouTube页面的Chrome脚本的人)。这导致我这个特殊的堆栈溢出解决方案,基本上说,YouTube页面顶部的红色加载栏是一个CSS转换元素,并且它在完成时创建了一个 transitionend (区分大小写)事件。链接解决方案中的代码并不完整(对我来说),但它确实解释了如何实现工作解决方案。我的代码每页仅运行一次,这非常完美。所以这里是我现在拥有的:

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

$(youtubePageChange);

为了解释上面的代码,我首先运行一次代码,以便在第一次加载YouTube页面时例如通过在地址栏中输入网址)。然后对于每次需要进度条的后续点击,代码都会再次运行。



红色进度条代码



哦,为了将来的参考,当YouTube页面顶部出现红色进度条时,网站会临时在结尾添加一个新的 DIV BODY ,包含以下代码:

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


Since some time last year, YouTube made it so that every page is not actually loading an entirely new page, but primarily just re-loading the contents in div#content. You can notice this when you click on a link in YouTube and see the red loading bar at the top of the page.

I have a Greasemonkey script that modified elements on YouTube, but now that YouTube doesn't reload the entire page, the Greasemonkey script no longer fires on every "new" page. How can I make the Greasemonkey script fire on every "new" page that I load on YouTube?

I'm using jQuery in this Greasemonkey script. I tried using functions like .on() with DOMNodeInserted but I can't find the right combination to make it work properly. With the event listeners that I've been using, I end up running my script hundreds of times for each page load, such as with the following:

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

Another solution I was thinking of was making all links on YouTube load pages like normal, without the new way that they are doing it.

解决方案

I figured it out myself after some research. First off, I don't like solutions that use setTimeout. This is often one method suggested in favor over the deprecated DOMNodeInserted for instance (which I use in some of my scripts, but try to avoid as much as possible), but if possible, I always prefer a solution where the script actually executes after a specific event. I've posted the solution I initially used in the first section below, then the final solution I used in the second section. All code below requires jQuery.

Decent solution, but not the best

At first, I had a solution where I added a click event to all A elements, which would run a timer that ran my script after 2 seconds. This isn't elegant, because if the page loads quickly, then there's a split second where the script hasn't run. And if the page loads for more than two seconds, then the script doesn't run at all. Script below:

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

Much better solution

So I began looking for a solution that was related to what I wanted to accomplish. I eventually found other people with a similar problem to mine (such as people wanting to create a Chrome script that modifies YouTube pages). This led me to this particular Stack Overflow solution, which basically says that the red loading bar at the top of YouTube pages was a CSS transition element, and that it created a transitionend (case sensitive) event when it was finished. The code in the linked solution wasn't complete (for me anyway), but it did explain how to achieve a working solution. The code I have runs only once per page, which is perfect. So here's what I have now:

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

$(youtubePageChange);

To explain the code above, basically I run the code once for when you first load a YouTube page (such as by typing the URL in the address bar). Then for every subsequent click that requires the progress bar, the code runs again.

Red progress bar code

Oh, and for future reference, when the red progress bar appears at the top of YouTube pages, the site temporarily adds a new DIV to the end of BODY, with the following code:

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

这篇关于每次在YouTube上加载新页面时如何运行脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆