如何让浏览器 运行 javascript 代码被 dom 操纵注入?
How to make the browser run javascript code injected by dom manipulation?
我想提供一些其他页面可以包含的 html 片段。
html 内容看起来像这样:
<div id="coolIncludable" style="display:none"> <!--be invisible until you are finished initializing -->
<div>Cool stuff here</div>
<div>More cool stuff and so on...</div>
</div>
<script src="http://somehwere/jquery.js"></script>
<script src="http://somewhere/something.js"></script>
<script>
$(function(){$('#coolIncludable').show();});//<- actually contained in a script file, just for illustration
</script>
我打算使用此处详述的方法:https://www.w3schools.com/howto/howto_html_include.asp 进行实际的包含。假设页面看起来像这样:
<html>
<head>
</head>
<body>
<H1>Content before snippet</H1>
<div id="registerWrapper" html-include="http://somehwere/snippet.html">
No content loaded
</div>
<H1>Content after snippet</H1>
<script type="text/javascript" src="http://somehwere/html-include.js"></script>
</body>
</html>
html 代码片段可以正常加载和嵌入,但它附带的 javascript 永远不会执行。有没有办法嵌入内容,包括确保它们被执行的脚本?
更新
我应该明确表示我不希望控制嵌入页面,所以我不能依赖它加载 jQuery 或任何其他内容。因此,我避免在嵌入函数中使用 jQuery,并将自己限制为普通的 Javascript。加载 jQuery 是代码段末尾的标签会做的事情之一。
由于您使用的是 jQuery,因此您可以使用它内置的 load() 方法来执行您想要的操作
类似于:
HTML
<div class="include" data-include="page2.html"></div>
JS
$('.include').each(function(){
const $el = $(this), url = $el.data('include');
$el.load(url)
});
然后确保新内容的脚本标签在该内容下方。
回想起来,我的错误是显而易见的:
行$(function(){$('#coolIncludable').show();});
是什么意思
做?它执行$('#coolIncludable').show();
吗?不,它没有。它注册了一个 回调 来执行此操作,以便由 'load' 事件触发,该事件已经触发,并且不会再次触发。
另一方面,这确实是一个有争议的问题,因为代码甚至从未执行过。
以下是我对 javascript
动态加载的了解
直接注入脚本标签不起作用
- 通过设置 element.innerHtml 注入的脚本标签执行 不
<div id="snippet">
...
</div>
<!-- neither of these will be executed -->
<script type="text/javascript">alert("stuff");</script>
<script type="text/javascript" src="http://somewhere/script.js"></script>
动态创建脚本标签确实有效
有效的是按照本文所述的方式生成动态标签:JavaScript Madness: Dynamic Script Loading
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'helper.js';
head.appendChild(script);
//At this point (or soon after) the code in helper.js will be executed
您可以在加载脚本中执行此操作。我的加载脚本看起来像这样:
function importJsFiles(){
const scriptFiles = ["http://somewhere/jquery.js",
"http://somewhere/stuff.js",
"http://somewhere/bootstrapSnippet.js"];
for (let i = 0; i< scriptFiles.length; i++){
importJsFile(scriptFiles[i]);
}
}
function includeSnippet(){
//See https://www.w3schools.com/howto/howto_html_include.asp
//We still have to do it without jQuery,
//because at the time this executes the injected jquery.js
//hasn't run and we do not yet have jQuery available
}
importJsFiles();
//At this point, all script tags are created, but the scripts are NOT loaded yet
includeSnippet();
//At this point, the dom is in its final shape
bootstrapSnippet(); //<- This won't work, because the script tags injected by this code won't be evaluated until after this file/function/whatever returns
//bootstrapSnippet.js
function bootstrapSnippet(){
alert("Snippet JS running")
if (window.jQuery) {
alert("JQuery is avaliable"); //<- This will fire, because the new script
// tags are evaluated in order, and we put the
// jquery.js one before the bootstrapSnippet.js one
}
//So now we CAN do this:
$('#coolIncludable').show();
}
bootstrapSnippet();
this post 中有许多更有趣的想法和细节,我从上面的 link 中挑选出来。我希望有一天我能抽出时间来探索它们。
我想提供一些其他页面可以包含的 html 片段。
html 内容看起来像这样:
<div id="coolIncludable" style="display:none"> <!--be invisible until you are finished initializing -->
<div>Cool stuff here</div>
<div>More cool stuff and so on...</div>
</div>
<script src="http://somehwere/jquery.js"></script>
<script src="http://somewhere/something.js"></script>
<script>
$(function(){$('#coolIncludable').show();});//<- actually contained in a script file, just for illustration
</script>
我打算使用此处详述的方法:https://www.w3schools.com/howto/howto_html_include.asp 进行实际的包含。假设页面看起来像这样:
<html>
<head>
</head>
<body>
<H1>Content before snippet</H1>
<div id="registerWrapper" html-include="http://somehwere/snippet.html">
No content loaded
</div>
<H1>Content after snippet</H1>
<script type="text/javascript" src="http://somehwere/html-include.js"></script>
</body>
</html>
html 代码片段可以正常加载和嵌入,但它附带的 javascript 永远不会执行。有没有办法嵌入内容,包括确保它们被执行的脚本?
更新 我应该明确表示我不希望控制嵌入页面,所以我不能依赖它加载 jQuery 或任何其他内容。因此,我避免在嵌入函数中使用 jQuery,并将自己限制为普通的 Javascript。加载 jQuery 是代码段末尾的标签会做的事情之一。
由于您使用的是 jQuery,因此您可以使用它内置的 load() 方法来执行您想要的操作
类似于:
HTML
<div class="include" data-include="page2.html"></div>
JS
$('.include').each(function(){
const $el = $(this), url = $el.data('include');
$el.load(url)
});
然后确保新内容的脚本标签在该内容下方。
回想起来,我的错误是显而易见的:
行$(function(){$('#coolIncludable').show();});
是什么意思
做?它执行$('#coolIncludable').show();
吗?不,它没有。它注册了一个 回调 来执行此操作,以便由 'load' 事件触发,该事件已经触发,并且不会再次触发。
另一方面,这确实是一个有争议的问题,因为代码甚至从未执行过。
以下是我对 javascript
动态加载的了解直接注入脚本标签不起作用
- 通过设置 element.innerHtml 注入的脚本标签执行 不
<div id="snippet">
...
</div>
<!-- neither of these will be executed -->
<script type="text/javascript">alert("stuff");</script>
<script type="text/javascript" src="http://somewhere/script.js"></script>
动态创建脚本标签确实有效
有效的是按照本文所述的方式生成动态标签:JavaScript Madness: Dynamic Script Loading
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'helper.js';
head.appendChild(script);
//At this point (or soon after) the code in helper.js will be executed
您可以在加载脚本中执行此操作。我的加载脚本看起来像这样:
function importJsFiles(){
const scriptFiles = ["http://somewhere/jquery.js",
"http://somewhere/stuff.js",
"http://somewhere/bootstrapSnippet.js"];
for (let i = 0; i< scriptFiles.length; i++){
importJsFile(scriptFiles[i]);
}
}
function includeSnippet(){
//See https://www.w3schools.com/howto/howto_html_include.asp
//We still have to do it without jQuery,
//because at the time this executes the injected jquery.js
//hasn't run and we do not yet have jQuery available
}
importJsFiles();
//At this point, all script tags are created, but the scripts are NOT loaded yet
includeSnippet();
//At this point, the dom is in its final shape
bootstrapSnippet(); //<- This won't work, because the script tags injected by this code won't be evaluated until after this file/function/whatever returns
//bootstrapSnippet.js
function bootstrapSnippet(){
alert("Snippet JS running")
if (window.jQuery) {
alert("JQuery is avaliable"); //<- This will fire, because the new script
// tags are evaluated in order, and we put the
// jquery.js one before the bootstrapSnippet.js one
}
//So now we CAN do this:
$('#coolIncludable').show();
}
bootstrapSnippet();
this post 中有许多更有趣的想法和细节,我从上面的 link 中挑选出来。我希望有一天我能抽出时间来探索它们。