2009-08-16 3 views
1

J'ai deux types de liens qui sont liés à un événement. Si le lien cliqué est associé à la classe, le gestionnaire d'événements appelle recallFlag, sinon la fonction doFlag.jquery event.target est modifié pour afficher un élément non pertinent à l'intérieur d'ajax post callback?

$(document).ready(function() { 

$('div.flag-link, span.flag-link').bind('click', function(e){ 
    if ($(e.target).attr('class')=='flagged') doRecall(e); 
    else doFlag(e); 
    return false; 
}); 

La fonction doFlag charge un formulaire et, lorsque l'utilisateur le soumet, reçoit des données json. En utilisant ces données, il modifie href et la classe du lien (marqué -> non marqué et vice-versa).

Lorsque l'utilisateur marque un élément pour la première fois, l'exécution est correcte. Mais quand une seconde fois l'utilisateur clique sur un lien différent pour marquer un autre élément, j'ai un comportement étrange: event.target est changé en premier élément (qui a été cliqué à la première fois) dans la fonction de rappel de l'événement post . Par conséquent, un mauvais lien (le lien sur lequel vous avez cliqué précédemment) est mis à jour.

Qu'est-ce que je fais mal?

function doFlag(e) { 

    var link = e.target; 
    var $prnt = $(link).parent(); 
    var $url = $(link).attr('href'); 
    console.log('new attempt to flag:' + $(link).attr('href')); 

    Boxy.load($url, {modal:true, title:e.target.innerHTML, closeText:'[Kapat]', unloadOnHide:true, cache:false, behaviours: function(r) { 

    $("#flag-form-submit").live("click", function(){ 
     var post_url = $("#flag-form").attr('action'); 
     $.post(post_url, $("#flag-form").serialize(), function(data){ 

       //THIS IS WHERE THE CODE SCREWS UP: 
       //here "link" is changed to the former link that triggered the event previously  
       if (data.status == 'ok') { 

        $(link).attr('href', data.url); 
        $(link).attr('class', data.css_class); 
        $(link).attr('innerHTML', data.text); 
        $prnt.children('img.flag-img').css('visibility', 'visible'); 

       } 


      }, "json"); 
     boxy = Boxy.get(this); 
     boxy.hideAndUnload();      
     return false; 
    }); 
    } 
}); 

Répondre

2

C'est parce que vous utilisez un événement .live. Fondamentalement, vous devriez seulement lier cette session une fois par page, mais vous ajoutez un événement en direct à la pile à chaque fois, mais vous ne voyez que le premier ajouté après avoir cliqué sur le premier lien.

Pour le moins de changement de code au lieu de .live vous pouvez utiliser un clic, mais en vous assurant déliez d'abord

par exemple

$("#flag-form-submit").unbind('click').click(function(){ 
    var post_url = $("#flag-form").attr('action'); 
    ..... 

}); 

Si vous voulez factoriser une grande partie de celui-ci alors Je voudrais déplacer le gestionnaire en direct en dehors de cette fonction, le lier dans doc prêt, puis stocker le lien en cours en utilisant .data sur l'élément # flag-form-submit.

$("#flag-form-submit").data('currentLink', link); 

puis à l'intérieur l'événement en direct

if (data.status == 'ok') { 

     var $link = $("#flag-form-submit").data('currentLink'); 
     $link.attr('href', data.url); 
     $link.attr('class', data.css_class); 
     $link.attr('innerHTML', data.text); 
     $prnt.children('img.flag-img').css('visibility', 'visible'); 

} 
+0

Vous avez été très utile. En suivant vos conseils, j'ai ajouté $ (this) .die ('click'); à la fin de la fonction d'événement click. Il semble également fonctionner parfaitement. Est-ce que je peux continuer ou devrais-je utiliser l'une de vos solutions? – shanyu

+0

préférable d'utiliser le clic ou l'événement juste .one (fn). Il n'y a aucun avantage à utiliser Live lorsque vous modifiez l'implémentation à chaque fois. – redsquare

+0

J'ai d'abord utilisé le clic, mais je suis passé en mode live car l'utilisation du clic ne lia pas l'élément à l'événement. Je pensais que c'était dû au fait que les éléments de la forme n'étaient pas complètement chargés au moment de l'exécution du code de liaison d'événement. Par conséquent, je suis passé à vivre et ça a marché. Peu de temps, je ne sais pas comment je peux utiliser cliquez :) – shanyu

Questions connexes