新标签页无法调用当前页面challenge函数问题求助
问题分析与解决方案
你遇到的核心问题是跨窗口的函数作用域隔离——你当前页面的challenge函数属于当前窗口的全局作用域,而新打开的标签页(winEvent指向的窗口)有自己独立的全局环境,它根本找不到你当前页面里的challenge函数,所以winEvent.setInterval(challenge, ...)自然无法正常工作。
解决思路
要让新标签页能调用challenge函数,你需要把这个函数的定义注入到新标签页的全局作用域中,让它成为新窗口自己的函数。下面是具体的修改方案:
修改后的代码示例
function challenge() { var body = $("body").html(); if(body.match(/td\>([0-9]+)\<\/td\>/)[1] > 0){ // 找到可挑战的玩家链接 var url = body.match(/href="(\/game.php?.*challenge.*[0-9a-f]+)"/)[1].replace(/&amp;/g, '&'); // 打开新标签页 var winEvent = window.open(url, '_blank'); // 等待新标签页加载完成后注入函数和定时器 winEvent.onload = function() { // 在新窗口的全局作用域中定义challenge函数 winEvent.challenge = function() { var newBody = winEvent.$("body").html(); if(newBody.match(/td\>([0-9]+)\<\/td\>/)[1] > 0){ var newUrl = newBody.match(/href="(\/game.php?.*challenge.*[0-9a-f]+)"/)[1].replace(/&amp;/g, '&'); var newWin = winEvent.window.open(newUrl, '_blank'); var rand = Math.random() * (10 - 7) + 7; // 给新打开的标签页重复注入逻辑 newWin.onload = function() { newWin.challenge = winEvent.challenge; newWin.setInterval(newWin.challenge, rand*1000); }; winEvent.window.close(); } }; // 设置新标签页的定时器(随机7-10秒) var rand = Math.random() * (10 - 7) + 7; winEvent.setInterval(winEvent.challenge, rand*1000); }; // 关闭当前标签页(注意:只有脚本打开的标签页才能被脚本关闭) window.close(); } } // 初始定时器:每5秒检查一次当前页面 window.setInterval(challenge, 5*1000);
关键修改点说明
- 函数注入:通过
winEvent.challenge = function() {...}把challenge函数绑定到新窗口的全局对象上,这样新窗口的setInterval就能找到这个函数了。 - 等待页面加载:使用
winEvent.onload确保新标签页的DOM和资源(比如jQuery)加载完成后再执行逻辑,避免$未定义或DOM获取失败的问题。 - 递归注入:当新标签页再次打开下一个标签页时,同样把
challenge函数注入到新窗口中,保证逻辑能持续执行。
额外注意事项
- 同源限制:这个方案要求所有打开的标签页都和当前页面同源(协议、域名、端口一致),否则浏览器的同源策略会阻止你访问新窗口的
window对象,此时需要考虑其他方案(比如通过URL参数传递简单逻辑,但复杂度会更高)。 - jQuery依赖:确保每个新打开的标签页都加载了jQuery,否则
$会报错。如果目标页面没有jQuery,你可能需要在注入函数前先动态加载jQuery。 - 窗口关闭限制:浏览器通常只允许脚本关闭由脚本自己打开的标签页,如果当前标签页是用户手动打开的,
window.close()会被浏览器阻止。
内容的提问来源于stack exchange,提问作者h1569543
相关产品推荐
相关产品推荐

