2013-08-01 40 views
0

當我進行AJAX調用來替換div時,響應包含指向外部.js文件的腳本標記。但是,我無法得到返回的JS執行。我試圖eval()的迴應,但沒有奏效。我也嘗試從onComplete回調中調用外部.js文件中的函數,但這也不起作用。不知道還有什麼要做。我使用MooTools的核心1.4.5AJAX調用後Javascript文件不能執行

首頁的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,以免影響任何事情。

+0

「.js」腳本文件是否爲新的ajax調用? – Sergio

+0

該腳本是否標記了呈現的html?如果沒有,你可以發佈你的'blah.php',在你解析腳本的部分。可能與逃避標籤有關。 「響應」是怎麼樣的? – Sergio

+0

在第二個.js文件中,確實是另一個AJAX調用。我想通過AJAX調用第二頁時添加新的事件偵聽器。您看到的腳本標記是呈現的HTML的一部分。 blah.php中的腳本標記直接硬編碼(在MVC中,我將其硬編碼到視圖中)。即我不使用echo來輸出這個腳本標籤。 – ehz350

回答

2

domready將根據listing.js第二次爲您啓動,您的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(); 
    }); 
}); 

請記住,您對元素集合中項目的索引不夠安全。使用由後端提供的硬數據庫標識。這是不安全的,ppl可以修改他們的DOM,刪除元素並獲得他們不應該看到的ID。不是說他們不能這樣做,否則,但...

通過XHR引發腳本和評估響應是一種反模式,併爲您的頁面提供了針對XSS的攻擊矢量,請不要忘記這一點。

+0

感謝您的回覆!如何在不從標記中檢索硬編碼的情況下提供腳本?我理解它的方式是任何腳本獲得id的唯一方式是這個路徑:DB> PHP> HTML> JS。或者你是否說有一個晦澀難懂的ID可以避免攻擊? – ehz350

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

+0

感謝您的回答。我也試過這個,但無濟於事。我已經試過通過Firebug查看腳本是否被加載到DOM中。看起來不是。 – ehz350

+0

嗯......我可以有把握地認爲你撥打的是從「ajaxfunc」,即返回的功能:VAR N = ajaxfunc(事件); N(); –

+0

這個問題可以採取兩種方式。 1)ajaxfunc的返回值是另一個函數。這樣做是因爲使用閉合循環。所以是的,返回的這個函數確實被調用,並且通過AJAX調用來證明。 2)AJAX響應的.js文件沒有可調用的函數。相反,我希望它能自動觸發事件監聽器。但是,這不起作用。我點擊一個錨點,它無處可去。 – ehz350