在AJAX </script>检索的<div>内执行<script>

时间:2011-01-06 20:45:58

标签: javascript html ajax

有一个名为“内容”的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>

11 个答案:

答案 0 :(得分:61)

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

此其他StackOverflow帖子也可能对您有所帮助:Can scripts be inserted with innerHTML?

答案 1 :(得分:57)

我使用了这段代码,工作正常

var arr = MyDiv.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
    eval(arr[n].innerHTML)//run script inside div

答案 2 :(得分:13)

如果您通过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或其他库。

答案 3 :(得分:8)

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

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

答案 4 :(得分:4)

对于我来说,使用jQuery这只是“有效”,前提是您不要尝试将XHR返回的HTML的子集附加到文档中。 (参见this bug report显示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/

答案 5 :(得分:2)

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

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

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

答案 6 :(得分:2)

这是一个可以用来解析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;
 }

答案 7 :(得分:0)

我在这里发了一篇类似的帖子,addEventListener load on ajax load WITHOUT jquery

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

所以...

if(正在加载page1,pageload = 1)    运行函数registerListeners1

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

答案 8 :(得分:0)

通过从ajax .done:

调用每个脚本内容的eval,这对我有用
$.ajax({}).done(function (data) {      
    $('div#content script').each(function (index, element) { eval(element.innerHTML); 
})  
  

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

答案 9 :(得分:0)

我的结论是HTML不允许使用NESTED SCRIPT标签。如果您正在使用JavaScript注入其中包含脚本标签的HTML代码,则该脚本将无法正常工作,因为JavaScript也包含在脚本标签中。您可以使用下一个代码对其进行测试,结果将无法正常工作。用例是您正在使用AJAX或类似名称调用服务,正在获取HTML,并且想要直接将其注入HTML DOM。如果注入的HTML代码具有SCRIPT标记内部,将无法正常工作。

stopSliderAnimation

答案 10 :(得分:-2)

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

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

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

PS。需要Jquery