Tampermonkey脚本报错:函数未定义,求助作用域问题
解决Tampermonkey脚本中点击按钮找不到函数的问题
你的问题确实和作用域密切相关,咱们一步步拆解修复:
1. 核心问题:内联onclick访问不到IIFE内部的函数
你把所有函数都放在了自执行函数(IIFE)里面,这意味着这些函数只在这个局部作用域内有效。而按钮的onclick="startExtractor()"是在页面的全局作用域下去找startExtractor函数,自然会提示找不到。
2. 修复步骤
步骤1:替换内联onclick为jQuery事件绑定
不要用内联的onclick属性,改用jQuery的on()方法绑定事件,这样就能直接访问IIFE内部的函数了。修改siteSetup函数:
function siteSetup () { // 直接创建DOM元素,避免转义字符的麻烦 var newBox = $('<div id="fiddleBar"><button id="startButton">Test</button></div>'); newBox.insertBefore('#repTb'); // 绑定点击事件 $('#startButton').on('click', startExtractor); }
步骤2:修复siteSetup的调用错误
你代码里写的是siteSetup;,这只是引用函数,没有执行它,要改成siteSetup();。同时还要修正判断逻辑:$('#fiddleBar')永远返回jQuery对象,需要通过length判断元素是否存在:
if (!$('#fiddleBar').length) { siteSetup(); } else { console.log('Repeating Site Setup'); setTimeout(siteSetup,100); }
步骤3:修正GM权限的配置格式
@grant的写法建议每个权限单独声明,避免潜在的解析问题:
// ==UserScript== // @name Futbin Extractor // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @match https://www.futbin.com/players // @grant GM_getValue // @grant GM_setValue // ==/UserScript==
步骤4:补全变量声明
extractorRunning变量没有用let或var声明,会自动变成全局变量,建议在IIFE内部显式声明:
let extractorRunning = false; // 放在函数外部,作为模块内的共享变量 function startExtractor () { console.log('Starting Extractor'); extractorRunning = true; // 合并两个选择器,简化代码 $('.player_tr_1, .player_tr_2').each(function () { extract(this); }); };
完整修复后的脚本
// ==UserScript== // @name Futbin Extractor // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @match https://www.futbin.com/players // @grant GM_getValue // @grant GM_setValue // ==/UserScript== /* global $ */ (function() { 'use strict'; let extractorRunning = false; function extract (e) { // 这里写你的提取逻辑 console.log('Extracting element:', e); } function startExtractor () { console.log('Starting Extractor'); extractorRunning = true; // 合并选择器,简化遍历逻辑 $('.player_tr_1, .player_tr_2').each(function () { extract(this); }); }; function siteSetup () { var newBox = $('<div id="fiddleBar"><button id="startButton">Test</button></div>'); newBox.insertBefore('#repTb'); // 绑定点击事件到内部函数 $('#startButton').on('click', startExtractor); } // 修正判断逻辑和函数调用 if (!$('#fiddleBar').length) { siteSetup(); } else { console.log('Repeating Site Setup'); setTimeout(siteSetup,100); } })();
为什么之前用var定义函数可以?
当你用var startExtractor = function() {...}这种方式在IIFE外面定义时,var声明的变量会被提升到全局作用域,所以页面能访问到。但用function startExtractor() {...}在IIFE内部时,它是局部作用域的函数,全局环境根本看不到它。
内容的提问来源于stack exchange,提问作者Matt Bridges
相关产品推荐
相关产品推荐

