【问题标题】:Processing comments on YouTube's New Look处理有关 YouTube 新外观的评论
【发布时间】:2018-07-09 11:29:12
【问题描述】:

我正在为 Greasemonkey 创建一个用户脚本,用于在 YouTube 的 cmets 附近显示其他内容。我希望它同时支持 Classic 模式和 New Look(基于 Polymer,可以在 https://www.youtube.com/new 激活),并且我已经实现了我想要的大部分功能。

但我最近发现的一个主要问题与看似复杂的 YouTube 机制有关,涉及以下过程:

  • (1) 从缓存中加载第一批 cmets。

  • (2) 从缓存中加载更多批次的 cmets。

为了处理每条评论,我使用waitForKeyElements 来捕捉它们。
当我不离开当前页面时,这很有效。但是,当我在同一页面上打开不同的视频时,或者当我打开任何其他 YouTube 页面然后按返回时,内容会中断。

导航后,应该由脚本处理的 cmets 显示为已处理。当然,这就是 YouTube 的免重新加载设计的工作原理。

在某些时候,我能够让脚本识别导航事件yt-navigate-finish - 这解决了问题 (1)。但另一个问题 (2) 仍然存在 - 新批次的 cmets 出现缓存并被重新插入和重新填充。这是我找不到解决方案的地方。

为了演示这个问题,我创建了一个小的 Greasemonkey 脚本 (MCVE):

// ==UserScript==
// @name       TEST2
// @include    https://*youtube.com/*
// @require    https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
// @grant      none
// @run-at     document-start
// ==/UserScript==

waitForKeyElements('#main .style-scope ytd-comment-renderer', ParseItemTest);

function ParseItemTest(jNode) {
    var aNode = $(jNode).find("#author-text")[0];
    var newspan = document.createElement('span');
    newspan.innerHTML = ' <font color="red">===</font> ' + $(aNode).find("span.style-scope.ytd-comment-renderer").html();
  $(aNode).append(newspan);
}

function waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector) {
    var targetNodes, btargetsFound;
    if (typeof iframeSelector == "undefined") targetNodes = $(selectorTxt);
    else targetNodes = $(iframeSelector).contents().find(selectorTxt);
    if (targetNodes && targetNodes.length > 0) {
        btargetsFound = true;
        targetNodes.each(function() {
            var jThis = $(this);
            var alreadyFound = jThis.data('alreadyFound') || false;
            if (!alreadyFound) {
                var cancelFound = actionFunction(jThis);
                if (cancelFound) btargetsFound = false;
                else jThis.data('alreadyFound', true);
            }
        });
    } else {
        btargetsFound = false;
    }
    var controlObj = waitForKeyElements.controlObj || {};
    var controlKey = selectorTxt.replace(/[^\w]/g, "_");
    var timeControl = controlObj[controlKey];
    if (btargetsFound && bWaitOnce && timeControl) {
        clearInterval(timeControl);
        delete controlObj[controlKey];
    } else {
        if (!timeControl) {
            timeControl = setInterval(function() {
                waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector);
            }, 300);
            controlObj[controlKey] = timeControl;
        }
    }
    waitForKeyElements.controlObj = controlObj;
}

激活此脚本,启用 YouTube 的新外观并使用 cmets 转到任何视频。让他们加载,注意每个评论是如何添加用户名的,例如

爱丽丝 === 爱丽丝

约翰 === 约翰

格蕾丝 === 格蕾丝

打开任何其他页面并按返回后,您将看到以下内容:

爱丽丝 === 格蕾丝

约翰 === 约翰

格蕾丝 === 爱丽丝

在您转到另一个视频页面并检查 cmets 后,您会看到:

简 === 格蕾丝

多萝西 === 约翰

布拉德 === 爱丽丝

我希望这足以解释问题。我只需要抓住 YouTube 用新数据填充现有评论元素的时刻,然后用新数据再次解析它们。

【问题讨论】:

    标签: javascript jquery youtube greasemonkey tampermonkey


    【解决方案1】:

    感谢您的努力,布洛克·亚当斯。

    不过,我已经想出了一些类似的解决方案。如果这对任何人都有帮助,它的工作原理如下:

    • 我设置了MutationObserver,以观察&lt;paper-spinner-lite&gt; 对象的变化。
    • 对于每个发现的变化,我检查孩子div#main.style-scope.ytd-comment-renderer 是否有cooldown 类。适合我的逻辑:
    • 如果是,我会重新检查并重新处理每条评论。
    • 如果不是,我删除每个评论元素。 YouTube 会正确地重新初始化它们。

    (我以后有时间可能会发布实际代码。)

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 2016-05-28
    • 2022-01-24
    • 2010-12-03
    • 2012-11-07
    • 2012-11-05
    相关资源
    最近更新 更多