问个小白问题,如何让油猴脚本中的循环异步执行 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
zhuzhuaini
V2EX    Javascript

问个小白问题,如何让油猴脚本中的循环异步执行

  •  
  •   zhuzhuaini 2021-07-03 09:32:46 +08:00 4921 次点击
    这是一个创建于 1635 天前的主题,其中的信息可能已经有所发展或是发生改变。

    说下我的场景,一个动态加载的网页,他内容是再更新的,但是网页不刷新,这就导致了我的 JS 脚本只会被执行一次,那我就需要使用一个循环隔几秒钟就获取一下源码中的 element,如果匹配到了我要的元素,那就再执行之后的内容,如果没匹配到,那就接着循环。

    我目前写了之后,他会在网页加载的一瞬间就启动这个循环,然后会话就被这个循环占用了,网页就没响应了。。。所以我希望让这个循环 和 网页的正常浏览互不影响

    23 条回复    2021-07-03 15:08:04 +08:00
    codehz
        1
    codehz  
       2021-07-03 09:41:19 +08:00   1
    建议用 MutationObserver
    huixia0010
        2
    huixia0010  
       2021-07-03 09:57:16 +08:00   1
    时钟
    geebos
        3
    geebos  
    PRO
       2021-07-03 09:57:48 +08:00   1
    setInterval 回调
    wdssmq
        4
    wdssmq  
       2021-07-03 10:04:19 +08:00   1
    我一般设置鼠标移动监听
    flyhaozi
        5
    flyhaozi  
       2021-07-03 10:08:33 +08:00   1/span>
    Mutation Observer 就是用来在 DOM 变化时触发回调的,不需要手动循环检测
    如果要循环检测的话,应该用 setTimeout
    比如
    function foo() {
    var elm = document.querySelector('#selector')
    if(elm) {
    // 实际执行代码
    }else{
    setTimeout(foo, 1000) // 1000ms 后重新调用 foo (准确地说是将 foo 加入任务队列)
    }
    }
    xiaoming1992
        6
    xiaoming1992  
       2021-07-03 10:09:10 +08:00 via Android   1
    或者爬虫直接请求 api ?
    lemon6
        7
    lemon6  
       2021-07-03 10:52:56 +08:00 via Android   1
    settimeout 每隔几秒去检测一次
    sugarsalt
        8
    sugarsalt  
       2021-07-03 11:28:46 +08:00   1
    MutationObserver +1
    Huelse
        9
    Huelse  
       2021-07-03 11:37:04 +08:00   2
    如果是百度之类的网站 MutationObserver 会用不了,已经被覆盖了
    si
        10
    si  
       2021-07-03 11:52:59 +08:00   1
    setInterval,检测到了再 clearInterval
    flyhaozi
        11
    flyhaozi  
       2021-07-03 12:01:44 +08:00   1
    @Huelse 竟然给覆盖成了 null,好鸡贼
    不过试了下如果让脚本 @run-at document-start,使用 unsafeWindow 还是可以提前保存原始 MutationObserver 的引用
    isukkaw
        12
    isukkaw  
       2021-07-03 12:11:27 +08:00   3
    @flyhaozi #11 拿不到。

    document-start 依然是异步插入的、此时 Main Document 都跑完了。document-start 保证的只是脚本会在 DOMContentLoaded 发生前执行完。

    要想拿到引用,除非开启 油猴 Advanced Mode => Instant Inject 。
    flyhaozi
        13
    flyhaozi  
       2021-07-03 12:38:46 +08:00   1
    @isukkaw 可能不同用户脚本管理器的行为不一样?我用的 Tampermonkey 默认注入模式都还是拿得到
    测试脚本在这: https://pastebin.com/PXxQfFmw
    flyhaozi
        14
    flyhaozi  
       2021-07-03 12:55:16 +08:00   1
    @isukkaw 又试了下脚本运行时已经能获取到 head 的内容了,可能只是百度覆盖的比较晚。用这种方式的确不够稳定。
    zhuzhuaini
        15
    zhuzhuaini  
    OP
       2021-07-03 13:23:12 +08:00   1
    楼上说的 MutationObserver 我百度找了个示例代码然后改了改发现不能用 会报错。。已经用了 settimeout 完事了 感谢楼上各位!!!稍后送上我个人的爱心
    zhuzhuaini
        16
    zhuzhuaini  
    OP
       2021-07-03 13:24:30 +08:00   1
    MutationObserver 应该是用于检测一个元素 中属性的变化吧,而我要检测的比较特殊,他一开始没有这个元素,这个元素是后期动态加载出来的
    zhuzhuaini
        17
    zhuzhuaini  
    OP
       2021-07-03 13:25:18 +08:00   1
    所以这个报错应该是由于 油猴脚本在网页一刷新就把脚本跑起来了,找不到这个元素 ID 自然就报错了。。。
    flyhaozi
        18
    flyhaozi  
       2021-07-03 13:34:12 +08:00   1
    @zhuzhuaini #17 那就观察父节点,建议看看 MDN https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
    另外主题无关的回复就没必要感谢了,毕竟金币有限
    zhuzhuaini
        19
    zhuzhuaini  
    OP
       2021-07-03 13:50:32 +08:00
    @flyhaozi 哈哈 我看到的就是这个 好像谷歌第一条就是 我现在碰到一个问题 比如我通过 ID 定位到了一个元素 这个元素中有许多个 tr 标签,每个 tr 标签里都有一个 class 属性 class 中 有许多值 比如有叫“even-row ui-selectee" 也有叫”odd-row ui-selectee“ 也有”odd-row ui-selectee ui-selected“ 但不管他们怎么变,只要在 tr 中 class 里 带 ” ui-selected“ 就是我想筛选出来的,这有什么快捷的方案么,,目前我查了还没什么头绪,正在继续查找-.-
    zhuzhuaini
        20
    zhuzhuaini  
    OP
       2021-07-03 13:51:46 +08:00
    @flyhaozi 每个在我帖子下回复的都是花了金币的,我不能让人家光亏呀,总得给人回本~~~~
    flyhaozi
        21
    flyhaozi  
       2021-07-03 14:31:47 +08:00
    @zhuzhuaini #19 你说的是静态元素还是用 Mutation Observer 观察的,静态的话直接在定位到的元素上调用 querySelectorAll('tr.ui-selected')就可以了吧,会返回所有符合条件的元素的列表。
    zhuzhuaini
        22
    zhuzhuaini  
    OP
       2021-07-03 15:07:47 +08:00
    @flyhaozi 静态的 这个要用到 jquery 我是在在油猴里面使用
    zhuzhuaini
        23
    zhuzhuaini  
    OP
       2021-07-03 15:08:04 +08:00
    @flyhaozi 我在油猴里面使用试试看!感谢!
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3688 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 00:52 PVG 08:52 LAX 16:52 JFK 19:52
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86