34 votes

Déclencheur $document.prêt (donc code AJAX je ne peux pas modifier est exécuté)

Mes besoins sont les suivants:

  • J'ai une riche page web qui à un certain moment, charge un tas de code HTML dans un div, via AJAX.
  • Le HTML, j'ai récupérer n'ont javascript (<script>...</script>)
  • L'extrait javascript contient $('document').ready( ... ) pièces
  • Je ne peux pas modifier l'extrait javascript; il s'agit d'une lib externe
  • J'ai une fonction javascript qui est appelée lorsque l'AJAX est chargé. Je suis en train de "truc" dans l'exécution en faisant:

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

Qui ne coupe pas, je le crains.

J'ai vu plusieurs réponses sur Débordement de Pile "échapper" à cette question, en changeant le code qui est retourné sur l'AJAX (faire une fonction et de l'appeler après le chargement, ou tout simplement supprimer l' $(document).ready()). J'ai besoin de stress que je ne peux pas changer l'extrait de code sur cette affaire.

21voto

John Boker Points 36308

Après quelques recherches, j'ai créé un moyen pour le faire fonctionner.

voici mon test de la montre de travail: http://www.antiyes.com/test/test2.php

voici le code correspondant:

<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>

ensuite, dans le corps, j'ai:

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

fondamentalement, ce que j'ai fait a été d'ajouter une fonction jQuery qui copie le readyList avant d'être autorisé à sortir, puis il sera disponible pour être utilisée par vous.

il ressemble le code ci-dessous ne fonctionne pas:

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

déposer les guillemets autour de document.

12voto

rakaloof Points 437

Depuis le jQuery readyList n'est pas exposée à partir de la version 1.4 (décrite ici) sympa les solutions ci-dessus sont cassés.

Un moyen de contourner cela est de créer votre propre readyList, par le biais de substitution de l'original jQuery-prêt de la méthode. Ceci doit être fait avant les autres scripts qui utilisent l'original, prêt de la méthode sont chargés. Sinon, il suffit de le même code que 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();});
};
})();

Je ne suis pas sûr de savoir si il est conseillé de remplacer le prêt de la méthode. Hésitez pas à me conseiller sur ce point. Je n'ai pas encore trouvé les effets secondaires moi-même bien que.

9voto

kikito Points 23229

Juste au cas où quelqu'un en a besoin, je raffinés John la solution d'un peu de sorte qu'il peut être utilisé directement comme un fichier 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();});
}

Y compris ce fichier à la suite notamment de jquery permet de déclenchement de prêt en invoquant $.triggerReady(). Exemple:

<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>

En passant, je voulais faire c' $(document).triggerReady(). Si quelqu'un est disposé à partager quelques conseils sur ce, mal-être apprécié.

6voto

Simone Gianni Points 51

Nous avons eu le même problème et résolu d'une autre manière.

Au lieu de

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

Nous avons utilisé :

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

jQuery va déclencher un "prêt" de l'événement sur le document, comme d'habitude. Lorsque l'on charge le contenu d'un nouveau div via ajax, on peut écrire:

loadedDiv.trigger('ready')

Et ont tous l'initialisation effectuée uniquement sur la div, l'obtention de ce qu'attend.

2voto

Uoli Points 88

Simone Gianni de Réponse, je pense que c'est le plus élégant et propre.

et vous pouvez même le simplifier pour devenir encore plus facile à utiliser:

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");
    });
};

Alors, maintenant, au lieu d'utiliser:

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

vous pouvez simplement utiliser:

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

ou:

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

Ceci a l'avantage d'appliquer seulement sur la gâchette de la div qui est en cours de mise à jour.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X