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

2022-12-14 23:07:56 +08:00
 lada05

这段代码在 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

1687 次点击
所在节点    程序员
10 条回复
hervey0424
2022-12-14 23:32:54 +08:00
试试这么写呢 hideLink.on('click', function(){})
lada05
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
2022-12-14 23:45:01 +08:00
试了下 tampermonkey 也是同样现象,所以应该与脚本管理器无关……
ragnaroks
2022-12-15 00:12:03 +08:00
userscript 中的 DOM 是被克隆的一份 safeWindow ,需要 "// @grant unsafeWindow" 之后使用 "unsafeWindow.document.querySelect..."
edis0n0
2022-12-15 00:24:13 +08:00
@ragnaroks #4 没写过脚本,想问问脚本管理器这样做的意义是什么,方便脚本往 clone 出来的 document 上建临时 canvas 之类的东西吗
coolan
2022-12-15 01:00:31 +08:00
Chrome+Tampermonkey 里你的脚本正常运行
lada05
2022-12-15 01:06:16 +08:00
@coolan #6 谢谢!同时很抱歉,求助前我忘记换个浏览器测试了!看来跟浏览器有关,这是百分浏览器(基于 Chromium 86.0.4240.198 的……可能太老了
Trim21
2022-12-15 02:05:53 +08:00
换成.on('click' 试试
autoxbc
2022-12-15 06:52:31 +08:00
@edis0n0 #5 脚本管理器希望实现一个沙盒,让用户脚本可以任意访问页面环境中的对象,而脚本有关的任何对象都无法被页面访问,以避免被探测和泄露数据

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

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

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

额外的,因为这种沙盒特性,绝大多数脚本作者有意把代码包裹在立即执行函数以避免污染全局对象的做法,实际上完全多余
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
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/902579

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX