2010-02-10 42 views
33

我的要求如下:

  • 我有豐富的網頁,在某一時刻加載了一堆HTML中一個div,通過AJAX。
  • 我檢索HTML確實具有的JavaScript(<script>...</script>
  • 所檢索的javascript包含$('document').ready(...)
  • 不能修改所檢索的javascript;它來自外部庫
  • 我有一個JavaScript函數,當AJAX加載時調用。我試圖「誘騙」到做執行:

    function AjaxLoaded() { 
        $('document').trigger('ready'); 
    } 
    

這不剪,我很害怕。

我見過severalresponses堆棧溢出,通過改變其在AJAX返回的代碼「迴避」這個問題(使它成爲一個功能,加載後調用它,或者只是刪除$(document).ready())。我需要強調的是,我無法在這種情況下更改檢索到的代碼。

+0

這是一個有趣的問題,我不得不看jQuery代碼,看看發生了什麼事到就緒事件。 – 2010-02-10 17:04:10

回答

21

在一些研究中,我創建了一種方法來使其工作。

,這裏是我的測試,表明它的工作:http://www.antiyes.com/test/test2.php

這裏是有關的代碼:

<script> 
    // easy copy of an array 
    Array.prototype.copy = function() { 
     return [].concat(this); 
    }; 

    // this function is added to jQuery, it allows access to the readylist 
    // it works for jQuery 1.3.2, it might break on future versions 
    $.getReadyList = function() { 
     if(this.readyList != null) 
      this.myreadylist = this.readyList.copy();  
     return this.myreadylist; 
    }; 

    $(document).ready(function() { 
     alert("blah"); 
    }); 

</script> 

<script> 

    // this should be added last so it gets all the ready event 
    $(document).ready(function() { 
     readylist = $.getReadyList(); 
    }); 

</script> 

然後在身體,我有:

<input type="button" onclick="$(readylist).each(function(){this();});" value="trigger ready" /> 

基本上我所做的是將一個函數添加到jQuery中,該函數在清除之前複製readyList,然後它將可供您使用。

它看起來像下面不工作的代碼:

function AjaxLoaded() { 
    $(document).trigger('ready'); 
} 

串門document引號。

+0

有意義,因爲文檔是對象而不是元素。 +1進行研究。 – 2010-02-10 17:11:06

+2

約翰,你完全用這個弄出了我的想法。這絕對是+1和正確的答案!只是一個小小的評論:除了提供測試頁面的鏈接之外,你還介意在答案中包含代碼嗎?這太好了,如果在兩年內改變你的主機:) – kikito 2010-02-10 20:50:45

+1

@egarcia會做 – 2010-02-10 21:33:08

9

爲了防止任何人需要它,我細化了John的解決方案,以便它可以直接用作包含的JavaScript文件。

// jquery_trigger_ready.js 
// this function is added to jQuery, it allows access to the readylist 
// it works for jQuery 1.3.2, it might break on future versions 
$.getReadyList = function() { 
    if(this.readyList != null) { this.myreadylist = [].concat(this.readyList); } 
    return this.myreadylist; 
}; 

$(document).ready(function() { 
    readylist = $.getReadyList(); 
}); 

$.triggerReady = function() { 
    $(readylist).each(function(){this();}); 
} 

包括jQuery的,包括後該文件允許觸發通過調用$.triggerReady()準備。例如:

<html> 
    <head> 
    <title>trigger ready event</title> 
    <script src="test2_files/jquery-1.js" type="text/javascript"></script> 
    <script src="jquery_trigger_ready.js" type="text/javascript"></script> 
    </head> 
    <body> 
    <input onclick="$.triggerReady();" value="trigger ready" type="button"> 
    <script type="text/javascript"> 
     $(document).ready(function(){ 
      alert("blah"); 
     }); 
    </script> 
    </body> 
</html> 

順便說一下,我想使它$(document).triggerReady()。如果有人願意分享一些建議,不理解。

+0

你的意思是$(document).__ proto __。triggerReady = function(){$(readylist).each(function(){this();}); }?我知道proto是貶值的,但它是Opera中唯一的作品... – SparK 2011-10-20 17:13:18

+1

對不起,我不知道你在說什麼。Opera不向$添加函數? – kikito 2011-10-21 15:52:59

+0

還有另一種使用原型的方法,但是opera只支持__proto__這種舊方法。順便說一句,在我的另一個評論中:不是使用$ .triggerReady,而是使用$(document).__ proto __。triggerReady,以便您可以使用$(document).triggerReady();像你想的那樣。 – SparK 2011-10-24 09:47:38

6

我們遇到了同樣的問題,並以另一種方式解決了問題。

而不是

$(document).ready(function() { 
    $('.specialClass').click(.... 

我們使用:

$(document).bind('ready', function(event) { 
    $('.specialClass', event.target).click(.. 

jQuery將觸發對文檔像往常一樣 「就緒」 事件。當我們加載通過AJAX一個新的div的內容,我們可以這樣寫:

loadedDiv.trigger('ready') 

而且只有在DIV上執行的所有初始化,獲得我們所期望的。

+1

我真的很喜歡這個解決方案,但自發布以來,已將它添加到jQuery文檔中: _「$(document).bind(」ready「,handler),已棄用jquery 1.8」_ 我已經嘗試切換到on(),它幾乎工作,除了文檔準備不會調用它。可能是因爲棄用或文檔的這一部分: _「如果ready事件已經被觸發,並且您嘗試綁定(」ready「)綁定的處理程序將不會被執行。」_ 有關如何創建該解決方案工作? – 2012-11-30 16:50:46

2

西蒙娜·吉安尼的答案,我認爲是最優雅,乾淨。

,你甚至可以把它簡化變得更加容易使用:

jQuery.fn.loadExtended = function(url,completeCallback){ 
    return this.load(url,function(responseText, textStatus, XMLHttpRequest) { 
     if (completeCallback !== undefined && completeCallback !== null) { 
      completeCallback(responseText, textStatus, XMLHttpRequest); 
     } 
     $(this).trigger("ready"); 
    }); 
}; 

所以,現在不是使用:

$(".container").load(url,function(responseText, textStatus, XMLHttpRequest) { 
    $(this).trigger("ready"); 
}); 

你可以使用:

$(".container").loadExtended("tag_cloud.html"); 

或:

$(".container").loadExtended("tag_cloud.html",function(){ 
    alert('callback function') 
}); 

這樣做的唯一的應用,就會向被更新的DIV觸發的優勢。

11

由於jQuery的readyList不暴露作爲版本1.4(討論here)上面的漂亮的解決方案被破壞。

解決的辦法是通過創建自己的readyList,通過覆蓋原來的jQuery的準備方法。這需要在使用原始就緒方法的其他腳本加載之前完成。否則只是與John/Kikito相同的代碼:

// Overrides jQuery-ready and makes it triggerable with $.triggerReady 
// This script needs to be included before other scripts using the jQuery-ready. 
// Tested with jQuery 1.7 
(function(){ 
var readyList = []; 

// Store a reference to the original ready method. 
var originalReadyMethod = jQuery.fn.ready; 

// Override jQuery.fn.ready 
jQuery.fn.ready = function(){ 
if(arguments.length && arguments.length > 0 && typeof arguments[0] === 'function') { 
    readyList.push(arguments[0]); 
} 

// Execute the original method. 
originalReadyMethod.apply(this, arguments); 
}; 

// Used to trigger all ready events 
$.triggerReady = function() { 
    $(readyList).each(function(){this();}); 
}; 
})(); 

我不確定是否建議覆蓋ready方法。隨意就此提出建議。儘管我自己還沒有發現任何副作用。

+1

請注意它是'$(readyList).each(function(){this();});',大寫L – 2011-11-30 10:12:38

+0

謝謝你指出!它已被糾正。 – rakaloof 2011-12-05 10:29:09

+0

真棒修復,謝謝! – Eugene 2011-12-30 19:10:02