[编辑:我用一个简单的示例替换原始的,令人困惑的问题来证明问题。]
背景
我正在尝试编写一个将在Chrome中运行的用户脚本。此脚本需要调用用户脚本之外的JavaScript函数AlertMe()
- 此函数是页面的一部分,包含在服务器端动态生成的变量,因此无法重新生成在我的用户脚本中写下这个函数。
代码
页面上的脚本(visit the page):
<script type="text/javascript">
function AlertMe()
{
alert("Function AlertMe was called!");
// then do stuff with strings that were dynamically generated
// on the server so that I can't easily rewrite this into the userscript
}
</script>
我的用户名(install it in Chrome):
function tryAlert()
{
if (typeof AlertMe == "undefined") {
console.log('AlertMe is undefined.');
window.setTimeout(tryAlert, 100);
}
else {
AlertMe();
}
}
tryAlert();
问题
当我尝试简单地调用该功能时,Chrome的控制台让我知道AlertMe is not defined
。认为这是因为我的用户脚本在加载所有其他脚本之前运行,我使用setTimeout
等待AlertMe
函数被定义。
不幸的是,如果您安装脚本然后访问该页面,您将看到它只是永远输出AlertMe is undefined.
并且从不调用该函数。如果您在Chrome控制台中输入typeof AlertMe
,它会正确回复"function"
,那么为什么我的用户脚本始终认为AlertMe
未定义?
答案 0 :(得分:8)
您总是可以编写一个小函数来检查函数是否已加载
function waitForFnc(){
if(typeof absearch == "undefined"){
window.setTimeout(waitForFnc,50);
}
else{
runMyFunction();
}
}
function runMyFunction(){
var urlParams = window.location.search.substring(1).split('&'),
username = "",
hscEmailInput = document.getElementById('userfield6'),
i = 0;
if (urlParams !== "") {
for (i = 0; i < urlParams.length; i++) {
if (urlParams[i].substr(0,4) === "USER") {
username = urlParams[i].replace('USER=', '');
hscEmailInput.value = username + '@example.com';
absearch('&PAGESIZE=1');
}
}
}
}
waitForFnc();
答案 1 :(得分:7)
这不是时间问题。
您正在遇到Greasemonkey的安全限制,这会阻止您执行页面中的功能。请参阅我之前的问题的答案,以获得解释和一些安全的解决方法:
UserScripts & Greasemonkey: calling a website's JavaScript functions
答案 2 :(得分:-1)
如果确实问题确实是你的脚本运行得太早,那么检查并等待DOM准备好就是解决方案:Relying on DOM readiness to invoke a function (instead of window.onload)
修改强>
This answer on SO也可能有用。