UserScript 无法在 DOM 中找到元素

3

我有一个简单的用户脚本,旨在更改YouTube页面上的一些链接:

// ==UserScript==
// @name           name
// @description    description
// @include        https://www.youtube.com/*
// @match          https://www.youtube.com/*
// ==/UserScript==

var titles = document.getElementsByClassName("vm-video-title-content");

for (var i=0; i<titles.length; i++) {
    titles[i].setAttribute("href", titles[i].getAttribute("href").replace("/edit?o=U&video_id", "watch?v"));
}

当我将代码用作书签脚本或仅将其粘贴到控制台中时,代码能够正常工作,但在安装为用户脚本的 Chrome 中似乎没有效果。

我尝试使用window.onloadwindow.addEventListener()来使代码在页面加载后运行,但这并没有帮助代码正常工作。

如何使这段代码在用户脚本中正常工作?


2
为了好玩,尝试将整个内容放入setTimeout中。我发现在编写用户脚本时,竞争条件是一个常见的问题... 给它足够的时间(大约一秒钟)开始执行。 - Shadow
1
@shadow 虽然这可能解决问题,但使用计时器解决异步代码问题几乎从来不是一个好的实践。 - 4castle
1
如果您不熟悉用户脚本的工作原理,请不要发表评论。更多信息请参见此处~http://stackoverflow.com/tags/userscripts/info - Phil
2
@4castle - 尽管这不是一个好的实践方式,但对于调试来说非常有用。而且考虑到这只是一个用户脚本,我认为这并不重要... - Shadow
2
// @run-at - 这是Greasemonkey的文档,但Tampermonkey在元块中使用相同的概念 - 这里是 Tampermonkey 文档关于 run-at 的说明。 - Jaromanda X
显示剩余4条评论
1个回答

3
使用元块@run-at属性允许您决定何时注入(因此运行)代码。
由于需要等待DOM完成加载,因此您将使用。
// @run-at document-end

但是,由于这似乎是默认设置,也许你需要

// @run-at document-idle

如果代码依赖于“动态”内容的加载,那么您可能会遇到麻烦,不得不观察DOM中的变化(使用MutationObserver)。
在这种情况下,您需要尽早注入脚本 - 甚至可能要这样做。
// @run-at document-start

setTimeout 应该是最后的选择,只有在万不得已的情况下才使用它!


嗨,我想知道你是从哪里学习 JavaScript 的。(非讽刺) - Tilak Madichetti
我主要是通过渗透学习了JavaScript(这个回答有点傻,但事实是我从未正式学习过JavaScript - 我只是做它)。 - Jaromanda X
@run-at 在 Tampermonkey/Greasemonkey 之外是否有效?我不使用任何用户脚本管理器,只是在 chrome://extensions 上安装用户脚本。我还打算与其他人分享这个用户脚本,并希望避免告诉他们“您需要安装另一个扩展程序才能使其正常工作”,尤其是对于如此简单的代码。 - user7881662
我不知道@user7881662 - 你试过了吗?(我不常用Chrome,我在Firefox上使用Tampermonkey) - Jaromanda X
查看文档 - 在Chromium / Google Chrome中,默认情况下将Greasemonkey脚本注入到称为“document-idle”的新点 - 这表明即使这个答案也无法帮助,因为document-idle是注入脚本的最新时间点 - 我担心使用MutationObserver和一个添加得如此晚的脚本可能会有问题。 - Jaromanda X
我已经尝试了你提到的所有值,但似乎都没有帮助。当我尝试安装用户脚本时,使用 @run-at document-body 会导致“无效的脚本标题”错误,因此我认为Chrome可以识别其他值是正确的。 - user7881662

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接