zip11 发表于 2024-1-29 15:19:50

bilibili-脚本运行失效

本帖最后由 zip11 于 2024-1-29 18:00 编辑



想获取 所有视频的 的链接

[https://space.bilibili.com/809048/channel/seriesdetail?sid=2906939&ctype=0](https://space.bilibili.com/809048/channel/seriesdetail?sid=2906939&ctype=0)

编写的程序,在控制台运行,获取了链接,显示出了
可是放在 脚本猫里面 ,就没有 链接输出显示了

```
    function getElementsByClass(className) {
      return document.getElementsByClassName(className);
    }

    // 获取具有 "example-class" 类的所有元素
    var elements = getElementsByClass("title");

    // 遍历所有具有 "example-class" 类的元素
    for (var i = 0; i < elements.length; i++) {
      console.log(elements);
    }
   
```


---

通过 李恒道 的回答,发觉网页 视频链接 是异步加载的,需要等待元素出现,

异步获取元素的脚本库 ElementGetter
https://bbs.tampermonkey.net.cn/thread-2726-1-1.html

```
// @require   https://scriptcat.org/lib/513/2.0.0/ElementGetter.js

(function() {

    console.log("test-st");

    elmGetter.get('').then(div => {
      console.log(div);
      console.log("元素出现");
    });
})();

```

李恒道 发表于 2024-1-29 15:19:51

https://learn.scriptcat.org/docs/question/%E5%B8%B8%E8%A7%81%E8%AF%AF%E5%8C%BA1/

面加载不等于元素已经出现,我们通常在 f12 控制台调试和查看的是现有的页面,并不代表页面加载完毕后就一定具备这个元素

尽管很多页面会在加载的时候就出现所有元素

但是也有很多页面,会在渲染完毕后,再根据 xhr 请求数据等方式,再在页面上绘制新的数据,这个时候如果我们在页面加载完毕和获取数据绘制之间进行获取元素

是获取不到的。

解决方法也很简单,

这里我提供两个常见的方法

1.使用 setInterval 来进行循环判断,当获取元素不为空的时候继续执行,但需要注意不要创建过多的定时器,以及不使用的时候可以考虑销毁定时器,这里以找 class 名为 main 的元素为例。

let timer = setInterval(() => {
if (document.querySelector(".main") !== null) {
    //找到了定时器
    clearInterval(timer);
}
}, 1000);

2.通过 DOM 插入监控来判断

在 bilibili 的例子中我们已经搞过了,通过上层已经存在的元素对其进行 dom 监听,然后再插入的时候会触发这个函数,来进行一些操作

但是需要注意把握好下层元素的数量问题,如果绘制元素过多反复触发,会极大的延迟运行速度。

let ops = document.querySelector("#arc_toolbar_report .ops");
ops.addEventListener("DOMNodeInserted", function (event) {
    //触发了dom插入
});

如果对性能有一定的追求,可以考虑使用MutationObserve,也建议使用 cxxjackie 作者的 ElementGetter 库
页: [1]
查看完整版本: bilibili-脚本运行失效