2009-10-19 7 views
3

J'utilise jQuery pour attacher des plugins dans le gestionnaire $ (document) .ready() - par exemple, $ (". Date"). Datepicker (). Toutefois, lorsque je charge le contenu en utilisant $ ("... html ..."), par exemple à partir de $ .ajax (.., success (data) {}), ou d'ajaxForm ({target: ...}) , document.ready() n'est évidemment pas appelé. MISE À JOUR: comme l'a souligné est appelé mais je ne sais toujours pas quelle partie/élément a été chargé.

Je ne peux pas faire à nouveau ready() parce qu'il va rattacher les plugins une seconde fois aux éléments qui l'ont déjà. Donc, je dois le faire manuellement dans tous les cas, comme, je fais le succès (données) {item = $ (data); initDatePickerEtc (item); }

Y a-t-il un meilleur moyen?

Il ya Live Query plugin qui le fait pour les événements. Y at-il quelque chose qui me permettra de suivre la création d'éléments HTML et d'effectuer des actions alors? Quelque chose comme

$.oncreation(".date", function() { $(this).datepicker(); }); 
// or at least 
$.oncreation(function() { $(this).find(".date").datepicker(); }); 

Grande si elle traitera aussi des éléments existants ... comme Live fonctionne pour les requêtes existantes au moment de clic() appel, et les éléments d'avenir créés.

Notez que je serai content de ne suivre que les éléments créés par jQuery. Donc, soit jQuery fournit un point d'extension à sa fonction html() ou non, je suppose. Maintenant, à partir des sources jQuery non:

html: function(value) { 
    return value === undefined ? 
     (this[0] ? 
      this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") : 
      null) : 
     this.empty().append(value); 
}, 

Peut-être que si je remplace html() de sorte que même 3 ème plugins partie (par exemple ajaxForm) utiliseront ma version (qui se déclenche .Création $ callback) à la place de jQuery par défaut ... ça va marcher? Il y a des problèmes avec cette approche - ce n'est pas seulement html(), c'est append(), etc ... et ce serait génial d'obtenir l'événement seulement si le résultat de $ ("") est ajouté au document ... depuis quand c'est en mémoire je n'ai pas besoin de datepicker().

Répondre

2

S'il s'agit d'une option pour vous, vous pouvez inclure une instruction $ (document) .ready() dans le retourné html. La fonction transmise sera appelée après le rendu du code HTML retourné.

+0

Je devrai obtenir une référence à la partie chargée à partir de là. Si je fais $ (document) .ready (function() {$ ("*"). Css ('background-color', 'red');}); dans la partie chargée, la page WHOLE deviendra rouge au lieu de simplement div. – queen3

+0

oui. J'ai résolu cela en ajoutant une classe aux éléments et en filtrant quand je le répète: $ ('*'). not ('. doneAlready'). css (...). addClass ('doneAlready'); –

+0

Bonne approche et fonctionne, +1. Je me demande si le suivi dans un tableau global est meilleur - je suis réellement préoccupé par les grandes pages et l'ajout de classe à chaque élément ... semble être un hack. Donc j'espère des approches plus propres. Mais si aucun, je pense que je vais devoir accepter cette solution. – queen3

2

Ce que vous cherchez probablement sont les W3C mutation events, comme DOMNodeInserted et DOMNodeRemoved Malheureusement, ils ne sont pas pris en charge par tous les navigateurs (the IE family of browsers do not support them at all), donc nous devons examiner d'autres façons de réaliser la fonctionnalité multi-navigateur. La façon dont live() fonctionne est d'utiliser event delegation et il est possible que vous puissiez implémenter la délégation d'événements dans votre propre code. En tant que example,

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css" type="text/css" /> 
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script> 
<title>Demo</title> 
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
<script type="text/javascript"> 
$(function() { 
    $('.picker').datepicker(); 

    $('button').click(function() { 
     $(this).prev().before('<br/><input type="text" class="picker" />'); 
    }); 

    $('div.container').click(function(e) { 
     var target = $(e.target);  
     if (target.hasClass('picker') && !target.hasClass('hasDatepicker')) { 
     $(e.target).datepicker().datepicker('show'); 
     } 
    }); 
}); 
</script> 
</head> 
<body> 
<div class="container"> 
<input type="text" class="picker" /> 
<br/> 
<button>Add a new input</button> 
</div> 
</body> 
</html> 

nous vérifions ici la event.target sur le récipient <div> pour voir si elle a la classe picker et non la classe hasDatepicker (qui est ajouté par le plugin datepicker pour indiquer une entrée avec un datepicker attaché). Si le event.target répond aux critères, nous lions une datepicker, puis appelez datepicker('show') dessus. Si le event.target a déjà un dateur de date attaché alors en cliquant sur l'entrée montrera le dateur de date et si event.target n'a pas picker class ou aucun datpicker attaché, alors rien ne se passera.

J'ai choisi datepicker comme vous l'avez mentionné dans votre question, mais l'idée de délégation d'événement peut être appliquée dans de nombreuses circonstances différentes, cependant, not all events bubble.

+0

Super écrit! Si vous avez besoin d'une délégation d'événements sur des événements qui ne bougent pas, vous pouvez utiliser livequery - http://docs.jquery.com/Plugins/livequery - Il a des performances moins bonnes que la délégation d'événement de style jquery $ .live, mais il peut attraper les événements qui ne pétillent pas. À votre santé. –

+0

Vous ne savez pas comment les événements peuvent m'aider - quel est l'événement pour html()/append()? Eh bien, sauf ceux que je ne peux pas utiliser parce que les utilisateurs travaillent encore avec IE6 ... – queen3

0

Vous pouvez créer une routine qui effectue l'initialisation du plugin portée à un objet racine jQuery particulier. Quelque chose comme ceci:

function AttachPlugins(jq) { 
    jq.Find('.date').datepicker(); 
    // other stuff 
} 

Votre document gestionnaire prêt peut l'appeler comme:

$(document).ready(function(){ 
    AttachPlugins($(body)); 
}); 

Bien que votre gestionnaire Ajax peut l'appeler comme ça

var newElement = $(html); 
AttachPlugins(newEleemnt); 

Il est pas totalement automatisé, mais ne devrait pas être. Le HTML Ajax doit être considéré comme "frais" et non traité. Attacher automatiquement des plugins me convulse comme le font les déclencheurs SQL. Au moins avec mon approche, vous réutilisez le même code que celui utilisé pour attacher les plugins.

+0

Comme je l'ai dit, voici ce que je fais maintenant: "Je fais le succès (données) {item = $ (data); initDatePickerEtc (article); }." – queen3

+0

Ma réponse est différente. Ma réponse spécifie que vous appelez la même fonction depuis ready et depuis le callback Ajax. Vous n'avez pas dit que vous appelez initDatePickerEtc de votre gestionnaire prêt, ni initDatePickerEtc ne semble prendre un argument jq pour étendre l'opération. –

Questions connexes