您正在异步加载 jQuery(尽管有script.async=false
),然后在此之后立即加载警报脚本。该脚本运行时尚未加载 jQuery,因此您将获得未定义的jQuery
引用。
作为一个快速修复,我添加了一个setInterval()
等待直到jQuery
被定义。我还进行了以下其他更改:
- 删除了
script.async = false;
这两个地方,因为它没有任何好处。
- 去掉了
$('iframe').load()
包装。当我测试您的代码时,该包装器中的回调函数根本不会被调用。这并不奇怪,因为此时没有任何内容被加载到 iframe 中。
document.createElement()
更改了您用来使用 iframe 文档(iframedoc
在我的版本中调用)的两个地方。使用它可以正常工作document
,但我更愿意在它们将被加载到的文档下创建这些脚本。
- 将 的两个实例更改
...find(something)[0].appendChild();
为更简单的...find(something).append();
.
这是工作代码:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript">
</script>
<title>iFrame Test</title>
</head>
<body>
<script type="text/javascript">
$(function() {
var $contents = $('iframe').contents();
var iframedoc = $contents[0];
var insertScript = function(src) {
var script = iframedoc.createElement('script');
script.type = 'text/javascript';
script.src = src;
$('iframe').contents().find('head').append(script);
}
var insertScriptContent = function(code) {
var script = iframedoc.createElement('script');
script.type = 'text/javascript';
script.innerHTML = code;
$('iframe').contents().find('body').append(script);
}
insertScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js');
insertScriptContent(
'var timer = setInterval( function() {' +
'if( typeof jQuery == "undefined" ) return;' +
'clearInterval( timer );' +
'jQuery(function(){ alert("loaded"); });' +
'}, 50 )'
);
});
</script>
<div class="output">
<iframe></iframe>
</div>
</body>
</html>
这对于第一次通过来说很好,但是有一种更简单的方法可以做到这一点。我尝试用 jQuery 代码替换这两个脚本函数,所以这是另一个工作版本:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript">
</script>
<title>iFrame Test</title>
</head>
<body>
<script type="text/javascript">
$(function() {
var $contents = $('iframe').contents();
$contents.find('head').append(
'<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"><\/script>'
);
$contents.find('body').append(
'<script>' +
'jQuery(function(){ alert("loaded"); });' +
'<\/script>'
);
});
</script>
<div class="output">
<iframe></iframe>
</div>
</body>
</html>
奇怪的是,这个没有setInterval()
计时器就可以正常工作,所以我把那个代码拿出来了。我不确定为什么会这样——这不是一种令人欣慰的感觉——但它在我测试过的浏览器中似乎是一致的。
最后,这是一个无效的实验。过去,我使用过document.write()
针对 iframe 的效果。所以我想我会尝试:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript">
</script>
<title>iFrame Test</title>
</head>
<body>
<script type="text/javascript">
$(function() {
var $contents = $('iframe').contents();
var iframedoc = $contents[0];
iframedoc.write(
'<!doctype html>',
'<html>',
'<head>',
'<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.js"><\/script>',
'</head>',
'<body>',
'<script>',
'debugger;',
'jQuery( function(){ alert("loaded"); } );',
'<\/script>',
'</body>',
'</html>'
);
});
</script>
<div class="output">
<iframe></iframe>
</div>
</body>
</html>
这个版本确实将 jQuery 和内联脚本加载到 iframe 中,并在内jQuery()
联脚本中执行调用。但它从不调用带有alert()
in 的回调函数。这实际上与我正在做的事情有关,所以我明天可能会再看一遍,但同时我留下了实验代码,以防你好奇。我将其更改为在 iframe 中使用未压缩的 jQuery 以便于调试,并debugger;
在其中留下了一条语句。