0

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

在该 listings.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,以防万一。

4

2 回答 2

2

根据 Listings.js, Nodomready将再次为您触发,您的 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 集合中项目的索引,这不太安全。使用后端提供的硬 db id。这是不安全的,人们可以修改他们的 DOM,删除元素并获取他们不应该看到的 id。并不是说他们不能这样做,而是……

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

于 2013-08-01T14:14:07.420 回答
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

于 2013-08-01T07:04:52.260 回答