V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lada05
V2EX  ›  程序员

为什么 jQuery .click 在 console 有效,在 userscript 无效?

  •  
  •   lada05 · 2022-12-14 23:07:56 +08:00 · 1697 次点击
    这是一个创建于 717 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这段代码在 console 里就正常,挪到 violentmonkey 里就不运行,请教下大佬为什么啊?有简洁的解决办法吗? T_T

    测试页面: https://www.naokr.com/question

    // ==UserScript==
    // @name         test - 点击 hide 后,隐藏相应的 item
    // @namespace    https://viayoo.com/
    // @version      20221214
    // @description  test
    // @author       You
    // @run-at       document-end
    // @match        *://*.naokr.com/*
    // @require      https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.min.js
    // @grant        none
    // ==/UserScript==
    
    function addHideLinkToPosts() {
        $("#question-list .question-item").each((index, el) => {
            var post = $(el);
            var caretMenu = post.find(".user-name");
            var hideLink = $('<span><a class="addon-hide-link" href="javascript:void(0)">Hide</a> &nbsp; </span>');
            hideLink.insertAfter(caretMenu);
            //=== 这行以上运行正常 就下面.click 不正常 点了没反应,但在 console 中正常 ===
            hideLink.click(function () {
                post.remove(); // hide the post now
                console.log("2222222222222222222222")
            });
    
        });
    }
    
    addHideLinkToPosts()
    

    ps:楼主文科生,写代码仅玩具性质自用,求别喷 T_T

    hervey0424
        1
    hervey0424  
       2022-12-14 23:32:54 +08:00   ❤️ 1
    试试这么写呢 hideLink.on('click', function(){})
    lada05
        2
    lada05  
    OP
       2022-12-14 23:39:51 +08:00
    @hervey0424 #1 谢谢帮助!试了这种写法,也是在 console 中有效,但在 violentmonkey 中无效
    搜到一篇 stackoverflow: https://stackoverflow.com/questions/20362839/why-cant-i-generate-a-click-event-directly-from-my-user-script
    但看了好像没啥关联……
    lada05
        3
    lada05  
    OP
       2022-12-14 23:45:01 +08:00
    试了下 tampermonkey 也是同样现象,所以应该与脚本管理器无关……
    ragnaroks
        4
    ragnaroks  
       2022-12-15 00:12:03 +08:00   ❤️ 1
    userscript 中的 DOM 是被克隆的一份 safeWindow ,需要 "// @grant unsafeWindow" 之后使用 "unsafeWindow.document.querySelect..."
    edis0n0
        5
    edis0n0  
       2022-12-15 00:24:13 +08:00
    @ragnaroks #4 没写过脚本,想问问脚本管理器这样做的意义是什么,方便脚本往 clone 出来的 document 上建临时 canvas 之类的东西吗
    coolan
        6
    coolan  
       2022-12-15 01:00:31 +08:00   ❤️ 1
    Chrome+Tampermonkey 里你的脚本正常运行
    lada05
        7
    lada05  
    OP
       2022-12-15 01:06:16 +08:00
    @coolan #6 谢谢!同时很抱歉,求助前我忘记换个浏览器测试了!看来跟浏览器有关,这是百分浏览器(基于 Chromium 86.0.4240.198 的……可能太老了
    Trim21
        8
    Trim21  
       2022-12-15 02:05:53 +08:00 via Android
    换成.on('click' 试试
    autoxbc
        9
    autoxbc  
       2022-12-15 06:52:31 +08:00   ❤️ 2
    @edis0n0 #5 脚本管理器希望实现一个沙盒,让用户脚本可以任意访问页面环境中的对象,而脚本有关的任何对象都无法被页面访问,以避免被探测和泄露数据

    所以用户脚本对顶层对象的任何写操作实际都是写入一个替身对象
    globalThis.testValue = 42
    这句代码不会在页面环境里留下任何痕迹,但是 testValue 还能被用户脚本读取
    unsafeWindow.testValue = 42
    这句就是打破沙盒显式写入页面环境

    不过,二级对象并不受这个沙盒的保护
    document.testValue = 42
    这句代码就会真实的写入页面环境
    并不需要 unsafeWindow.document.testValue 这种操作

    同时,对页面环境的读操作不受任何限制,所以并不需要在读取时使用 unsafeWindow

    额外的,因为这种沙盒特性,绝大多数脚本作者有意把代码包裹在立即执行函数以避免污染全局对象的做法,实际上完全多余
    ysc3839
        10
    ysc3839  
       2022-12-15 12:22:24 +08:00
    @autoxbc 包裹在立即执行函数可能是为了兼容老版本的 GreaseMonkey ,当时 GreaseMonkey 漏洞很多的,unsafeWindow 也是那个时候加入的。现在的用户脚本管理器本身就会包裹一层再执行,比如 Violentmonkey:
    ```
    window.VMino8uixxkddudjxaug=function({GM,GM_info,unsafeWindow,cloneInto,createObjectIn,exportFunction}){((define,module,exports)=>{// ==UserScript==
    // @name New script
    // @namespace Violentmonkey Scripts
    // @match *://v2ex.com/*
    // @grant none
    // @version 1.0
    // @author -
    // ==/UserScript==
    debugger;
    })()}
    //# sourceURL=chrome-extension://jinjaccalgkegednnccohejagnlnfdag/New%20script.user.js#32
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1116 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 23:48 · PVG 07:48 · LAX 15:48 · JFK 18:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.