我正在尝试首先创建一个iframe
,然后向其中注入jQuery库,然后发出警告,说明jQuery已经加载。
正在按预期将jQuery库插入iframe
头部,并且jQuery上的警报会加载到正文中。
问题是,它没有显示警告,而是显示jQuery is not defined
。
有人可以提出任何建议吗?
这是代码
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<title>iFrame Test</title>
</head>
<body>
<script>
var insertScript = function(src){
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = false;
script.src = src;
$('iframe').contents().find('head')[0].appendChild(script);
}
var insertScriptContent = function(code){
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = false;
script.innerHTML = code;
$('iframe').contents().find('body')[0].appendChild(script);
}
$(function(){
$('iframe').load(function(){
var contents = $('iframe').contents();
insertScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js');
insertScriptContent('jQuery(function(){ alert("loaded"); });');
});
});
</script>
<div class="output">
<iframe></iframe>
</div>
</body>
</html>
答案 0 :(得分:2)
您正在异步加载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()
调用回调函数。这实际上与我正在做的事情有关,所以我明天可能会再看一下它,但与此同时我留下了实验代码以防你好奇。我将其更改为在iframe中使用未压缩的jQuery以便于调试,并在其中留下debugger;
语句。