javascript - 在AJAX检索的<div>中执行<script>

有一个名为“内容”的div:

<div id="content"></div>

它应该填充来自PHP文件的数据,通过AJAX,包括<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>
JCOC611 asked 2019-09-10T14:57:06Z
11个解决方案
60 votes

作为DOM文本插入的JavaScript将不会执行。 但是,您可以使用动态脚本模式来实现目标。 基本思想是将要执行的脚本移动到外部文件中,并在获得Ajax响应时创建脚本标记。 然后,设置脚本标记的src属性,然后加载并执行外部脚本。

这个其他StackOverflow帖子也可能对您有所帮助:可以使用innerHTML插入脚本吗?

Chocula answered 2019-09-10T14:57:29Z
57 votes

我用过这段代码,工作正常

var arr = MyDiv.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
    eval(arr[n].innerHTML)//run script inside div
Firas Nizam answered 2019-09-10T14:57:54Z
12 votes

如果您通过Ajax在div中加载脚本块,如下所示:

<div id="content">
    <script type="text/javascript">
    function myFunction() {
      //do something
    }
    myFunction();
    </script>
</div>

...它只是更新页面的DOM,myFunction()不一定会被调用。

您可以使用Ajax回调方法(例如jQuery的ajax()方法中的方法)来定义请求完成时要执行的操作。

你正在做的不同于从一开始就加载包含JavaScript的页面(它确实被执行)。

获取某些内容后如何使用成功回调和错误回调的示例:

  $.ajax({
    type: 'GET',
    url: 'response.php',
    timeout: 2000,
    success: function(data) {
      $("#content").html(data);
      myFunction();
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
      alert("error retrieving content");
    }

另一种快速而肮脏的方法是使用eval()执行您作为DOM文本插入的任何脚本代码,如果您不想使用jQuery或其他库。

Christopher Tokar answered 2019-09-10T14:58:59Z
8 votes

以下是将评估文本中所有脚本标记的脚本。

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);
  }
}

从服务器收到HTML后,只需调用此函数即可。 请注意:使用eval可能很危险。

演示:[http://plnkr.co/edit/LA7OPkRfAtgOhwcAnLrl?p=preview]

Evgenii answered 2019-09-10T14:59:46Z
4 votes

如果您不尝试将XHR返回的HTML子集附加到文档中,那么这对我来说“正常”是使用jQuery的。 (请参阅此错误报告,显示jQuery的问题。)

这是一个显示它工作的示例:

<!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>

这相当于上面的内容:[http://jsfiddle.net/2CTLH/]

Phrogz answered 2019-09-10T15:00:31Z
2 votes

如果您正在注入需要脚本标记的内容,则可能会收到未捕获的语法错误并说出非法令牌。 为避免这种情况,请务必在结束脚本标记中转义正斜杠。即;

var output += '<\/script>';

任何结束标记也是如此,例如表单标记。

TommyRay answered 2019-09-10T15:01:07Z
2 votes

这是一个可以用来解析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;
 }
Andre Van Zuydam answered 2019-09-10T15:01:33Z
0 votes

我在这里有一个类似的帖子,addEventListener加载ajax加载WITHOUT jquery

我如何解决它是在我的stateChange函数中插入函数调用。 我设置的页面是3个按钮,可以将3个不同的页面加载到contentArea中。 因为我必须知道按下哪个按钮来加载第1,2或3页,所以我可以轻松地使用if / else语句来确定正在加载哪个页面然后运行哪个函数。 我试图做的是注册不同的按钮监听器,这些监听器只能在特定页面由于元素ID加载时起作用。

所以...

如果(正在加载第1页,页面加载= 1)运行函数registerListener 1

然后第2页或第3页相同。

Richard Chase answered 2019-09-10T15:02:27Z
0 votes

通过从ajax .done调用每个脚本内容的eval,这对我有用:

$.ajax({}).done(function (data) {      
    $('div#content script').each(function (index, element) { eval(element.innerHTML); 
})  

注意:我没有为$ .ajax编写参数,你必须调整它们   根据你的ajax。

shivgre answered 2019-09-10T15:03:00Z
0 votes

我的结论是HTML不允许使用NESTED SCRIPT标签。 如果您使用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>
Antonio Martin answered 2019-09-10T15:03:26Z
-2 votes

另一件事是使用以下脚本加载页面:

<div id="content" onmouseover='myFunction();$(this).prop( 'onmouseover', null );'>
<script type="text/javascript">
function myFunction() {
  //do something
}
myFunction();
</script>
</div>

这将加载页面,然后运行脚本并在运行该函数时删除事件处理程序。 在ajax加载后,这不会立即运行,但如果您正在等待用户输入div元素,这将正常工作。

PS。 需要Jquery

Joshua Klein answered 2019-09-10T15:04:08Z
translate from https://stackoverflow.com:/questions/4619668/executing-script-inside-div-retrieved-by-ajax