AJAX调用后Javascript文件没有执行

时间:2013-08-01 06:54:04

标签: javascript ajax mootools

当我进行AJAX调用以替换div时,响应包含指向外部.js文件的脚本标记。但是,我无法让返回的JS执行。我试过eval()响应但是没有用。我还尝试从onComplete回调中调用外部.js文件中的函数,但这也不起作用。不知道还能做什么。我正在使用mootools core 1.4.5

主页的JS

window.addEvent('domready', function(){  

    function ajaxfunc(i)
    {
        return function(e){
            e.stop();
            var requestData = new Request({
               url: 'blah.php?cat=' + i,
               evalScripts: true,
               evalResponse: true,
                   onComplete: function(response){
                       $('rt-main').set('html', response);
                   }
            });
            requestData.send();
        };
    }

    var total = $('cat_table').getChildren('div').length;
    for(var i=1; i<=total; i++)
    {
       $('catClick'+i).addEvent('click', ajaxfunc(i));
    }


});

返回的HTML

<script src="listings.js" type="text/javascript"></script>
...(other markup, etc)

在那个listing.js文件里面

window.addEvent('domready', function(){  

    function gotoItem(i)
    {
       return function(e){
          e.stop();
          var id= i;
          var requestData = new Request ({
             url: 'blah.php?id='+id,
             onComplete: function(response){
                $('rt-main').set('html', response);
             }
          });
          requestData.send();
       };
    }

   $$('.itemBox').each(function(el){
      el.getElement('a.itemClick').addEvent('click', gotoItem(el.id)); 
   });

});

我正在工作的环境是Joomla 3.1,以防任何事情发生。

2 个答案:

答案 0 :(得分:2)

根据listing.js,没有domready会为你开第二次,你的DOM已经准备好了。

您可以事先手动执行window.removeEvents('domready'),然后通过XHR加载并执行window.fireEvent('domready')来运行它。

如果你使用事件委托,你可以避免在初始ajax请求之后运行任何js,你只需要这样的东西。

window.addEvent('domready', function () {
    var ct = document.id('cat_table'),
        divs = ct.getChildren('div'), //need a more qualified selector
        rtMain = document.id('rt-main');

    divs.each(function(el, i){
        // store the index, if you don't have it as an attribute like id, rel or data-id
        el.store('index', i);
    });

    ct.addEvent('click:relay(div)', function(e){ // needs more qualified also.
        e && e.stop();

        new Request({
            method: 'get', // not post, check - faster
            url: 'blah.php?cat=' + this.retrieve('index'),
            evalResponse: true,
            onComplete: function(){
                rtMain.set('html', this.response.text);
            }
        }).send();
    });

    // delegation, assumes .itemBox are children of rtMain - just delegate to other parent otherwise.
    rtMain.addEvent('click:relay(.itemBox)', function(e){
        // reliance on index in collection is bad, try to change response above to contain data-id.
        e.stop();

        new Request({
            method: 'get',
            url: 'blah.php?id=' + this.get('data-id'), 
            onComplete: function(){
                rtMain.set('html', this.response.text);
            }
        }).send();
    });
});

请记住,您依赖Elements集合中项目的索引,这不太安全。使用后端提供的硬数据库ID。这是不安全的,ppl可以修改他们的DOM,删除元素并获得他们不应该看到的ID。不是说他们不能这样做但是......

通过XHR引入脚本并评估响应是一种反模式,并为您的页面提供XSS攻击的矢量,不要忘记。

答案 1 :(得分:0)

看起来链接的.js中的脚本包含在'domready'事件中,但是(我在这里假设一点)dom已经解雇了ready事件。尝试删除window.addEvent('domready', function(){ ...}包装器。

编辑,因为你说并非如此,如果不是返回脚本标记,你只需返回脚本并将其附加到页面上就可以了:

onComplete: function (response) {
    //
    var script = document.createElement('script');
    script.innerHTML = response;
    document.getElementById('rt-main').appendChild(script);

}
编辑我刚刚玩了一点,似乎我有一个不太优雅的解决方案fiddle