2010-03-23 9 views
1

Salutations Guru's, C'est un peu difficile à expliquer, mais je vais tenter le coup.jQuery .live feu plusieurs fois!

J'ai une petite question concernant la fonction .live() dans JQuery. Je vais simplifier l'exemple ici. J'ai une page "index.php" qui a un conteneur "#display_files_container" qui est rempli avec des liens d'ancrage qui sont générés dynamiquement par une page différente "process.php". Les liens sont chargés dans ce même <div> lorsque ces liens sont sélectionnés en fonction des attributs de ce lien. Voir Exemples:

index.php

<html> 

<head><title>index.php</title> 

<!-- this function below loads process.php and passes it the dirid variable via post. I then use this post variable inside of process.php to pull other links from the database --> 

<script language="text/javascript"> 
    $('.directory').live("click", function() { 
      $('#display_files_container').load('plugins/project_files/process.php', {dirid: $(this).attr('dirid')}); 
    }); 
</script> 

</head> 

<?php 
/*This code initial populates the link array so we have the first links populated before the users clicks for the first time*/ 
some code to fetch the $current_directory_list array from the database initially.... 
>? 

<body> 
<div id='display_files_container'> 

<?php 

/*Cycle through the array and echo out all the links which have been pulled from DB*/ 
for($i=0;$i<$current_directory_count;$i++) { 
    echo "<a href='#' class='directory' dirid='".$current_directory_list[$i]['id']." '>".$current_directory_list[$i]['directory_name']. 
    "</a> "; 
} 

?> 

</div> 
</body> 
</html> 

process.php

ce fichier inclut du code pour remplir le tableau de current_directory_list de $ [] à partir de la base de données en fonction de la poste variable « $ _POST ['dirid'] "qui a été envoyé à partir de la méthode .click() dans index.php. Il résout alors les résultats et nous les affichons dans le conteneur #display_files_container. Lorsque vous cliquez sur ces liens, le processus se répète.

Cela fonctionne ..... vous pouvez cliquer sur l'arborescence et charger les nouveaux liens à chaque fois. Cependant, il semble vouloir .load() le fichier process.php plusieurs fois pour un clic. Le nombre de fois que process.php est chargé semble augmenter au fur et à mesure que l'on clique sur les liens. Donc, par exemple, vous pouvez cliquer sur un lien et les rapports firebug que process.php a été chargé 23 fois ..... J'imagine que j'enregistrerais un stackoverflow. S'il vous plaît laissez-moi savoir si vous avez des idées. Y at-il des moyens que je peux assurer que .live() charge le fichier process.php une seule fois?

Merci, -CS

+0

Qu'est-ce que .directory? Est-ce un bouton, ou votre div wrapper principal? – Catfish

+0

donner la version complète et pas un simplifié .. comme le problème pourrait ne pas exister dans la version simplifiée .. –

+0

puis-je voir la source générée plutôt que le php? – mcgrailm

Répondre

5

Ce qui arrive, est que chaque fois que vous cliquez sur un lien, vous lient nouveau gestionnaire d'événements clic pour chaque lien. Ceci est possible car il peut y avoir plusieurs gestionnaires pour l'événement particulier. Vous devez retourner false dans votre gestionnaire pour arrêter l'événement.

Mise à jour: Je ne sais pas pourquoi le gestionnaire est lié plusieurs fois, mais je suppose qu'il a quelque chose à voir avec la nature particulière de l'implémentation de 'l'événement en direct'. Voir le chapitre Délégation événement du docs:

Le gestionnaire est passé à .live() est jamais lié à un élément; à la place, .live() lie un gestionnaire spécial à la racine de l'arborescence DOM.

Une autre solution consiste à utiliser bind() ou cliquez sur() au lieu de vivre() et appeler explicitement après l'ajax a été chargé:

function bind_link_handler() { 
    $('.directory').click(function() { 
     $('#display_files_container').load('...', bind_link_handler); 
    }) 
} 
+0

Merci Yaggo, en mettant 'return false' a fait l'affaire. Juste pour que je sache exactement ce qui se passe, pouvez-vous expliquer un peu pourquoi retourner faux était nécessaire. – cstrzelc

+0

De la documentation, "Pour empêcher d'autres gestionnaires d'exécuter après une utilisation liée.live(), le gestionnaire doit retourner false. Appeler .stopPropagation() n'effectuera pas ceci. ". Notez que ceci juste un tour de travail - vos liens ont toujours plusieurs gestionnaires, return false empêche simplement plus d'un exécutant – jholster

+0

' return false' ne fonctionne pas dans 1.5. 1 ... J'ai dû appeler 'die' puis appeler' live'. Http://stackoverflow.com/questions/6120943/why-is-this-jquery-ajax-click-event-firing-multiple-times/6121501 # 6121501 – Martin

1

Juste pour que tout le monde est dans la boucle mon nouveau La ligne du code .live() ressemble à ceci:

$('.directory').live("click", function() { 
    $('#display_files_container').load('plugins/project_files/process.php', {dirid: $(this).attr('dirid')}); 
    return false; 
});