我正在为Greasemonkey创建一个用户脚本,用于在YouTube中的评论附近显示其他内容。我希望它支持Classic模式和New Look(基于Polymer,可以在https://www.youtube.com/new激活),并且我已经实现了我想要的大部分功能。
但我最近发现的一个主要问题是涉及明显复杂的YouTube机制,涉及以下过程:
(1)从缓存中加载第一批评论。
(2)从缓存中加载任何其他批注释。
要对每条评论进行处理,我会使用waitForKeyElements
来抓住它们
当我不离开当前页面时,这很有效。但是,当我在同一页面上打开不同的视频时,或者当我打开任何其他YouTube页面然后按“返回”时,内容会中断。
导航后,脚本应处理的注释已经处理完毕。当然,这就是YouTube的无重载设计的工作原理。
在某些时候,我能够使脚本识别导航事件yt-navigate-finish
- 这解决了问题(1)。但另一个问题(2)仍然存在 - 新批量的评论会出现缓存并重新插入并重新填充。这是我找不到解决方案的地方。
为了演示这个问题,我已经创建了一个小的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的新外观并转到任何带评论的视频。让他们加载,记下每个评论如何添加用户名,例如
Alice === Alice
约翰===约翰
Grace === Grace
打开任何其他页面并按返回后,您将看到以下内容:
Alice === Grace
约翰===约翰
Grace === Alice
在您转到另一个视频页面并查看评论后,您会看到:
Jane === Grace
多萝西===约翰
布拉德===爱丽丝
我希望这足以解释这个问题。我只需要抓住YouTube用新数据填充现有评论元素的时刻,再用新数据解析它们。
答案 0 :(得分:0)
感谢你的努力,Brock Adams。
但是我已经提出了类似的解决方案。如果这有助于任何人,这是它的工作原理:
MutationObserver
,以观察<paper-spinner-lite>
个对象的变化。div#main.style-scope.ytd-comment-renderer
是否有cooldown
课程。对我有用的逻辑:(我可以稍后在有空的时候发布实际代码。)