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 · 149 天前 · 2109 次点击
    这是一个创建于 149 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    要想拿到引用,除非开启 油猴 Advanced Mode => Instant Inject 。
    flyhaozi
        13
    flyhaozi   149 天前   ❤️ 1
    @isukkaw 可能不同用户脚本管理器的行为不一样?我用的 Tampermonkey 默认注入模式都还是拿得到🤔
    测试脚本在这: https://pastebin.com/PXxQfFmw
    flyhaozi
        14
    flyhaozi   149 天前   ❤️ 1
    @isukkaw 又试了下脚本运行时已经能获取到 head 的内容了,可能只是百度覆盖的比较晚。用这种方式的确不够稳定。
    zhuzhuaini
        15
    zhuzhuaini   149 天前   ❤️ 1
    楼上说的 MutationObserver 我百度找了个示例代码然后改了改发现不能用 会报错。。已经用了 settimeout 完事了 感谢楼上各位!!!稍后送上我个人的爱心
    zhuzhuaini
        16
    zhuzhuaini   149 天前   ❤️ 1
    MutationObserver 应该是用于检测一个元素 中属性的变化吧,而我要检测的比较特殊,他一开始没有这个元素,这个元素是后期动态加载出来的
    zhuzhuaini
        17
    zhuzhuaini   149 天前   ❤️ 1
    所以这个报错应该是由于 油猴脚本在网页一刷新就把脚本跑起来了,找不到这个元素 ID 自然就报错了。。。
    flyhaozi
        18
    flyhaozi   149 天前   ❤️ 1
    @zhuzhuaini #17 那就观察父节点,建议看看 MDN https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
    另外主题无关的回复就没必要感谢了,毕竟金币有限😂
    zhuzhuaini
        19
    zhuzhuaini   149 天前
    @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   149 天前
    @flyhaozi 每个在我帖子下回复的都是花了金币的,我不能让人家光亏呀,总得给人回本~~~~
    flyhaozi
        21
    flyhaozi   149 天前
    @zhuzhuaini #19 你说的是静态元素还是用 Mutation Observer 观察的,静态的话直接在定位到的元素上调用 querySelectorAll('tr.ui-selected')就可以了吧,会返回所有符合条件的元素的列表。
    zhuzhuaini
        22
    zhuzhuaini   149 天前
    @flyhaozi 静态的 这个要用到 jquery 我是在在油猴里面使用
    zhuzhuaini
        23
    zhuzhuaini   149 天前
    @flyhaozi 我在油猴里面使用试试看!感谢!
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1121 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 107ms · UTC 20:24 · PVG 04:24 · LAX 12:24 · JFK 15:24
    ♥ Do have faith in what you're doing.