【问题标题】:Why doesn't this script work with successive page clicks?为什么此脚本不适用于连续的页面点击?
【发布时间】:2013-09-27 19:07:17
【问题描述】:

我目前在 Google Chrome 的 Tampermonkey 中使用以下脚本:

// ==UserScript==
// @name        Youtube opt in Ads per channel
// @namespace   schippi
// @include     http://www.youtube.com/watch*
// @version     1
// ==/UserScript==

var u = window.location.href;
if (u.search("user=") == -1) {
   var cont = document.getElementById("watch7-user-header").innerHTML;
   var user=cont.replace(/.+\/user\//i,'').replace(/\?(?:.|\s)*/m,'');
   window.location.href = u+"&user="+user;
}

它似乎在带有 Greasemonkey 的 Firefox 中完美运行,但在 Google Chrome 中,它似乎只适用于第一次点击 YouTube 视频。

更具体地说,如果我点击 YouTube 视频:
youtube.com/watch?v=MijmeoH9LT4,
它会将我重定向到:
youtube.com/watch?v=MijmeoH9LT4&user=Computerphile

但是,如果我点击相关视频垂直栏中的视频,它似乎不会进行任何进一步的重定向。

【问题讨论】:

  • @BrockAdams:嗯..它似乎仍然不起作用。新脚本:pastie.org/pastes/8347656/text
  • 是的,这是同样的种类问题,但由于 YouTube 不再触发 hashchange 事件,因此解决方案并不完全相同。稍后我会发布答案。

标签: javascript youtube cross-browser greasemonkey tampermonkey


【解决方案1】:

唉,在 Chrome 中仍然没有真正“简洁”的方法来做到这一点。 (Firefox 有更多选择。)

您最好的选择就是投票location.search;见下文。

不推荐您在 Chrome 中的其他选项,当前,但这里它们仅供参考:

  • Hack into the history.pushState function。这可以更快地通知页面更改,但在您运行代码之前会触发,因此它仍然需要一个计时器。此外,它还会在用户脚本环境中带来跨范围问题。
  • 使用 Mutation Observers 来监控 <title> 标签的变化。这可能可以正常工作,但可能会在您想要它之后触发,从而导致延迟和发音为“闪烁”。也可能无法在设计不佳的页面上运行(YouTube 没问题)。


另请注意,问题中的replace() 语句在某些情况下会炸毁 URL 和 404 脚本。使用 DOM 方法获取用户(见下文)。


轮询代码(简单、健壮、跨浏览器):

// ==UserScript==
// @name        Youtube opt in Ads per channel
// @namespace   schippi
// @include     http://www.youtube.com/watch*
// @version     1
// @grant       GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/
var elemCheckTimer      = null;
var pageURLCheckTimer   = setInterval (
    function () {
        if (this.lastQueryStr !== location.search) {
            this.lastQueryStr = location.search;
            gmMain ();
        }
    }
    , 111   //-- Nine times a second. Plenty fast w/o bogging page
);

function gmMain () {
    if ( ! /user=/.test (window.location.href) ) {
       elemCheckTimer = setInterval (checkUserAndRelocate, 24);
    }
}

function checkUserAndRelocate () {
    var elem        = document.querySelector (
        "#watch7-user-header a[href*='/user/']"
    );
    if (elem) {
        clearInterval (elemCheckTimer);
        var user    = elem.href.match (/\/user\/(\w+)\W?/);
        if (user  &&  user.length > 1) {
            location.replace (location.href + "&user=" + user[1]);
        }
    }
}

【讨论】:

  • 脚本可能已过时。如果您单击它,它会将用户置于主页上。而且它不会在没有重新加载的情况下将其放在视频上。
  • @Gopoi,是的,YouTube 变化很快。我将把它放在队列中重新检查,但这个问题似乎没什么兴趣 - 所以它的优先级很低。
  • 我自己正在检查它,看看我是否可以修复它。奇怪的是,脚本在 /watch 页面上似乎没有启动,但在重新加载后它会启动。可能是篡改问题?另外,当退出页面(按下 youtube 主页按钮)时,user= 会卡在导致错误的地址中。我尝试了第一个脚本并将第二个替换更改为 /\"(?:.|\s)*/m 匹配终止“,但脚本不执行。在调试窗口中,它显示脚本已排队,但它从未执行过。
  • @Gopoi,这是与 AJAX 相关的行为。而且,谷歌拥有的网站是一个特别痛苦的脚本。 (对于初学者来说,您看到的“YouTube”可能与我看到的“YouTube”有很大不同。)
猜你喜欢
  • 2011-09-20
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多