2010-02-10 64 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