Javascript 在 AJAX 检索到的 <div> 中执行 <script>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4619668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Executing <script> inside <div> retrieved by AJAX
提问by JCOC611
There's a div called "Content":
有一个名为“内容”的 div:
<div id="content"></div>
It should be filled with data from a PHP file, by AJAX, including a <script>
tag. However, the script inside this tag is not being executed.
它应该通过 AJAX 填充来自 PHP 文件的数据,包括一个<script>
标记。但是,该标签内的脚本没有被执行。
<div id="content"><!-- After AJAX loads the stuff that goes here -->
<script type="text/javascript">
//code
</script>
<!-- More stuff that DOES work here -->
</div>
采纳答案by Chocula
JavaScript inserted as DOM text will not execute. However, you can use the dynamic script patternto accomplish your goal. The basic idea is to move the script that you want to execute into an external file and create a script tag when you get your Ajax response. You then set the src
attribute of your script tag and voila, it loads and executes the external script.
作为 DOM 文本插入的 JavaScript 将不会执行。但是,您可以使用动态脚本模式来实现您的目标。基本思想是将要执行的脚本移动到外部文件中,并在获得 Ajax 响应时创建脚本标记。然后设置src
脚本标签的属性,瞧,它加载并执行外部脚本。
This other StackOverflow post may also be helpful to you: Can scripts be inserted with innerHTML?.
这篇 StackOverflow 的其他帖子也可能对您有所帮助:可以使用 innerHTML 插入脚本吗?.
回答by Firas Nizam
I used this code, it is working fine
我使用了这段代码,它工作正常
var arr = MyDiv.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
eval(arr[n].innerHTML)//run script inside div
回答by Christopher Tokar
If you load a script block within your div via Ajax like this:
如果您通过 Ajax 在 div 中加载脚本块,如下所示:
<div id="content">
<script type="text/javascript">
function myFunction() {
//do something
}
myFunction();
</script>
</div>
... it simply updates the DOM of your page, myFunction() does not necessarily get called.
...它只是更新页面的 DOM,myFunction() 不一定会被调用。
You can use an Ajax callback method such as the one in jQuery's ajax() method to define what to execute when the request finishes.
您可以使用 Ajax 回调方法(例如 jQuery 的ajax()方法中的方法)来定义在请求完成时要执行的内容。
What you are doing is different from loading a page with JavaScript included in it from the get-go (which does get executed).
您正在做的事情不同于从一开始就加载包含 JavaScript 的页面(确实会被执行)。
An example of how to used the success callback and error callback after fetching some content:
获取一些内容后如何使用成功回调和错误回调的示例:
$.ajax({
type: 'GET',
url: 'response.php',
timeout: 2000,
success: function(data) {
$("#content").html(data);
myFunction();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("error retrieving content");
}
Another quick and dirty way is to use eval()to execute any script code that you've inserted as DOM text if you don't want to use jQuery or other library.
如果您不想使用 jQuery 或其他库,另一种快速而肮脏的方法是使用eval()来执行您作为 DOM 文本插入的任何脚本代码。
回答by Evgenii
Here is the script that will evaluates all script tags in the text.
这是将评估文本中所有脚本标记的脚本。
function evalJSFromHtml(html) {
var newElement = document.createElement('div');
newElement.innerHTML = html;
var scripts = newElement.getElementsByTagName("script");
for (var i = 0; i < scripts.length; ++i) {
var script = scripts[i];
eval(script.innerHTML);
}
}
Just call this function after you receive your HTML from server. Be warned: using eval
can be dangerous.
从服务器收到 HTML 后调用此函数即可。请注意:使用eval
可能很危险。
回答by Phrogz
This 'just works' for me using jQuery, provided you don't try to append a subset the XHR-returned HTML to the document. (See this bug reportshowing the problem with jQuery.)
如果您不尝试将 XHR 返回的 HTML 的子集附加到文档中,这对我使用 jQuery 来说“只是有效”。(请参阅此错误报告,其中显示了 jQuery 的问题。)
Here is an example showing it working:
这是一个显示它工作的示例:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>test_1.4</title>
<script type="text/javascript" charset="utf-8" src="jquery.1.4.2.js"></script>
<script type="text/javascript" charset="utf-8">
var snippet = "<div><span id='a'>JS did not run<\/span><script type='text/javascript'>" +
"$('#a').html('Hooray! JS ran!');" +
"<\/script><\/div>";
$(function(){
$('#replaceable').replaceWith($(snippet));
});
</script>
</head>
<body>
<div id="replaceable">I'm going away.</div>
</body>
</html>
Here is the equivalent of the above: http://jsfiddle.net/2CTLH/
这是上面的等效项:http: //jsfiddle.net/2CTLH/
回答by Andre Van Zuydam
Here is a function you can use to parse AJAX responses, especially if you use minifiedjs and want it to execute the returned Javascript or just want to parse the scripts without adding them to the DOM, it handles exception errors as well. I used this code in php4sack library and it is useful outside of the library.
这是一个可用于解析 AJAX 响应的函数,特别是如果您使用 minifiedjs 并希望它执行返回的 Javascript 或只想解析脚本而不将它们添加到 DOM,它也可以处理异常错误。我在 php4sack 库中使用了这段代码,它在库之外很有用。
function parseScript(_source) {
var source = _source;
var scripts = new Array();
// Strip out tags
while(source.toLowerCase().indexOf("<script") > -1 || source.toLowerCase().indexOf("</script") > -1) {
var s = source.toLowerCase().indexOf("<script");
var s_e = source.indexOf(">", s);
var e = source.toLowerCase().indexOf("</script", s);
var e_e = source.indexOf(">", e);
// Add to scripts array
scripts.push(source.substring(s_e+1, e));
// Strip from source
source = source.substring(0, s) + source.substring(e_e+1);
}
// Loop through every script collected and eval it
for(var i=0; i<scripts.length; i++) {
try {
if (scripts[i] != '')
{
try { //IE
execScript(scripts[i]);
}
catch(ex) //Firefox
{
window.eval(scripts[i]);
}
}
}
catch(e) {
// do what you want here when a script fails
// window.alert('Script failed to run - '+scripts[i]);
if (e instanceof SyntaxError) console.log (e.message+' - '+scripts[i]);
}
}
// Return the cleaned source
return source;
}
回答by TommyRay
If you are injecting something that needs the script tag, you may get an uncaught syntax error and say illegal token. To avoid this, be sure to escape the forward slashes in your closing script tag(s). ie;
如果您正在注入需要脚本标记的内容,您可能会收到一个未捕获的语法错误并说非法令牌。为避免这种情况,请确保转义结束脚本标记中的正斜杠。IE;
var output += '<\/script>';
Same goes for any closing tags, such as a form tag.
任何结束标签也是如此,例如表单标签。
回答by Richard Chase
I had a similiar post here, addEventListener load on ajax load WITHOUT jquery
我在这里有一个类似的帖子,addEventListener load on ajax load WITHOUT jquery
How I solved it was to insert calls to functions within my stateChange function. The page I had setup was 3 buttons that would load 3 different pages into the contentArea. Because I had to know which button was being pressed to load page 1, 2 or 3, I could easily use if/else statements to determine which page is being loaded and then which function to run. What I was trying to do was register different button listeners that would only work when the specific page was loaded because of element IDs..
我如何解决它是在我的 stateChange 函数中插入对函数的调用。我设置的页面是 3 个按钮,可以将 3 个不同的页面加载到 contentArea 中。因为我必须知道按下哪个按钮来加载页面 1、2 或 3,所以我可以轻松地使用 if/else 语句来确定正在加载哪个页面,然后运行哪个函数。我试图做的是注册不同的按钮侦听器,这些侦听器仅在由于元素 ID 加载特定页面时才起作用。
so...
所以...
if (page1 is being loaded, pageload = 1) run function registerListeners1
如果(page1 正在加载,pageload = 1)运行函数 registerListeners1
then the same for page 2 or 3.
然后第 2 页或第 3 页相同。
回答by shivgre
This worked for me by calling eval on each script content from ajax .done :
通过对来自 ajax .done 的每个脚本内容调用 eval ,这对我有用:
$.ajax({}).done(function (data) {
$('div#content script').each(function (index, element) { eval(element.innerHTML);
})
Note: I didn't write parameters to $.ajax which you have to adjust according to your ajax.
注意:我没有将参数写入 $.ajax,您必须根据您的 ajax 进行调整。
回答by Antonio Martin
My conclusion is HTML doesn't allows NESTED SCRIPT tags. If you are using javascript for injecting HTML code that include script tags inside is not going to work because the javascript goes in a script tag too. You can test it with the next code and you will be that it's not going to work. The use case is you are calling a service with AJAX or similar, you are getting HTML and you want to inject it in the HTML DOM straight forward. If the injected HTML code has inside SCRIPT tags is not going to work.
我的结论是 HTML 不允许嵌套脚本标签。如果您使用 javascript 来注入包含脚本标签的 HTML 代码,则该代码将不起作用,因为 javascript 也包含在脚本标签中。你可以用下一个代码测试它,你会发现它不会工作。用例是您正在使用 AJAX 或类似方法调用服务,您正在获取 HTML 并且您想直接将其注入 HTML DOM 中。如果注入的 HTML 代码包含在 SCRIPT 标签中,则将无法工作。
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"></head><body></body><script>document.getElementsByTagName("body")[0].innerHTML = "<script>console.log('hi there')</script>\n<div>hello world</div>\n"</script></html>