在ajax加载页面后执行javascript脚本 - 不起作用

Posted

技术标签:

【中文标题】在ajax加载页面后执行javascript脚本 - 不起作用【英文标题】:Executing javascript script after ajax-loaded a page - doesn't work 【发布时间】:2012-06-08 22:34:30 【问题描述】:

我正在尝试使用 AJAX 获取页面,但是当我获取该页面并且它包含 javascript 代码时 - 它不会执行它。

为什么?

我的 ajax 页面中的简单代码:

<script type="text/javascript">
alert("Hello");
</script>

...它不执行它。我正在尝试使用 Google Maps API 并使用 AJAX 添加标记,所以每当我添加一个标记时,我都会执行一个获取新标记的 AJAX 页面,将其存储在数据库中,并且应该将标记“动态”添加到地图中。

但是由于我不能以这种方式执行单个 javascript 函数,我该怎么办?

我事先在页面上定义的函数是受保护的还是私有的?

** 使用 AJAX 功能更新 **

function ajaxExecute(id, link, query)

    if (query != null)
    
        query = query.replace("amp;", "");
    

    if (window.XMLHttpRequest)
    
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    
    else
    
        // code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    

    xmlhttp.onreadystatechange=function()
    
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        
            if (id != null)
            
                    document.getElementById(id).innerhtml=xmlhttp.responseText;
            
        
    

    if (query == null)
    
        xmlhttp.open("GET",link,true);
    
    else
    
        if (query.substr(0, 1) != "?")
        
            xmlhttp.open("GET",link+"?"+query,true);
        
        else
        
            xmlhttp.open("GET",link+query,true);
        
    
    xmlhttp.send();

** Deukalion 的解决方案 **

var content = xmlhttp.responseText;

if (id != null)


    document.getElementById(id).innerHTML=content;
    var script = content.match("<script[^>]*>[^<]*</script>");

    if (script != null)
    
        script = script.toString().replace('<script type="text/javascript">', '');
        script = script.replace('</script>', '');
        eval(script);

    

在某些事件上,我必须在脚本中添加事件侦听器,而不是仅仅创建一个“select onchange='executeFunctionNotIncludedInAjaxFile();'”,我必须为此添加事件侦听器(“change”,functionName,false)。在正在评估的脚本中。

【问题讨论】:

请提供一个发出 AJAX 请求并处理响应的代码示例。 【参考方案1】:

万一其他人偶然发现了这个旧线程,Deukalion 接受的答案存在一个问题,有一个问题可能被忽略了:正如所写,脚本仅查找 first em> 脚本标签。如果存在多个脚本标签,则忽略所有其他标签。

一些小的调整可以解决这个问题。换一行:

    var script = content.match("<script[^>]*>[^<]*</script>");

收件人:

    var script = content.match(/<script[^>]*>[^<]*<\/script>/g);

另一个来自:

    script = script.toString().replace('<script type="text/javascript">', '');

收件人:

    script = script.join("").replace(/<script type="text\/javascript">/g, '');

现在它将收集所有

【讨论】:

【参考方案2】:

当您通过将容器的innerHTML 设置为一些更新的内容来更新页面时,浏览器根本不会运行其中的脚本。您可以找到&lt;script&gt; 标签,获取它们的innerHTML(IE 可能更喜欢innerTEXT),然后自己eval() 脚本(这几乎是jQuery 所做的,尽管它会在更新之前找到带有正则表达式的脚本DOM)。

【讨论】:

我能够正则表达式脚本,所以我只能得到脚本。然后我对它们运行 eval,但它不适用于...说添加的 DOM 元素,其中包含引用未通过 AJAX 加载的主要函数的脚本。 如果服务器直接返回 javascript 怎么办?这将使eval 更易于使用。 (但要小心CSRF。) 当然可以;如果你得到的是纯 JavaScript,那就另当别论了。了解信任问题绝对很重要。【参考方案3】:

使用此功能:

function parseScript(_source) 
    var source = _source;
    var scripts = new Array();

    // Strip out tags
    while(source.indexOf("<script") > -1 || source.indexOf("</script") > -1) 
        var s = source.indexOf("<script");
        var s_e = source.indexOf(">", s);
        var e = source.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 
            eval(scripts[i]);
        
        catch(ex) 
            // do what you want here when a script fails
        
    

    // Return the cleaned source
    return source;

然后在替换/添加内容时执行parseScript(xmlhttp.responseText);

【讨论】:

【参考方案4】:

在 AJAX 请求之后,您可以创建一个“成功”函数,该函数可以获取返回的 html 并对其进行处理。 然后会执行一些东西。

如果有代码示例,那么我可以针对这种情况提供代码解决方案。但是只使用标准的 xmlhttprequest,可以做到以下几点:

xhr = new XMLHttpRequest();
xhr.open("GET","ajax_info.txt",true);
xhr.onreadystatechange=function()

if (xhr.readyState==4 && xhr.status==200)
  
  document.getElementById("myDiv").innerHTML = xhr.responseText;
  

xhr.send();
​

【讨论】:

我的方法看起来很相似,虽然我有一个更动态的 ajax 函数。它工作正常,除了执行javascripts。我会将代码添加到我的帖子中。 @Deukalion,没问题,我喜欢您在问题中发布的解决方案的灵活性。附言如果我的回答有帮助,请投票和/或检查答案。谢谢! :) 不,它没有。我的 php 文件包含一个简单的“alert()”,但它没有执行它。使用 Ajax 加载页面时,我无法访问静态构建的函数。

以上是关于在ajax加载页面后执行javascript脚本 - 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用 ajax 分页加载页面后重新初始化其他 javascript 函数

Yii: 如何在CGridView通过Ajax方式刷新数据后执行JS脚本

页面加载完成后执行javascript [重复]

Ajax 调用阻止其他 javascript 代码

ajax 加载内容与普通内容?

如何在 Ajax 加载后执行 javascript?