2010-06-13 10 views
5

mon problème réel est que la méthode .live() jQuery ne fonctionne pas.jQuery .live() ne fonctionne pas

Ce Sí le code où je l'utilise:

jQuery.fn.sb_animateMenuItem = function() 
    { 
    var mousehoverColor = '#0089F7'; 
    var duration = 250; 

    return this.each(function() 
    { 
     var originalColor = $(this).css('background-color'); 
     $(this).live('mouseover', function() 
     { 
      this.style.cursor = 'pointer'; 
      $(this).animate().stop(); 
      $(this).animate(
      { 
       backgroundColor: mousehoverColor 
      }, duration); 
     }); 
     $(this).live('mouseout', function() 
     { 
      this.style.cursor = 'default'; 
      $(this).animate(
      { 
       backgroundColor: originalColor 
      }, duration); 
     }); 
    }); 
}; 

Ce Snipped i est utilisé une autre page de cette façon:

<script type="text/javascript" src="ui/js/jquery-1.4.2.js"></script> 
<script type="text/javascript" src="ui/js/jquery-ui-1.8.1.custom.min.js"></script> 
<script type="text/javascript" src="ui/js/color.js"></script> 
<script type="text/javascript" src="engine/js/tiny_mce/tiny_mce.js"></script> 
<script type="text/javascript" src="ui/js/ui.js"></script> 
<script type="text/javascript"> 
    // UI effects 
    $(document).ready(function() 
    { 
     $('button').sb_animateButton(); 
     $('input').sb_animateInput(); 
     $('.top_menu_item').sb_animateMenuItem(); 
     $('.top_menu_item_right').sb_animateMenuItem(); 
     $('.left_menu_item').sb_animateMenuItem(); 
    }); 
</script> 

Depuis mon site utilise des requêtes AJAX i utilisé la méthode .live dans le premier extrait, mais quand je charge la page, les effets ne sont pas appliqués au bouton/entrée ... tags.

Si je supprime la méthode .live et que j'utilise la méthode "normale", les effets ui définis dans la première section sont appliqués mais seuls les éléments sont chargés avant toute requête AJAX. Les éléments chargés après la requête ajax ne sont pas affectés par le premier extrait (bien qu'ils aient le même sélecteur).

Merci de votre aide.

Répondre

16

En bref, vous ne pouvez pas utiliser .live() comme ça, il a suivre une base de sélection de quelque sorte, c'est from the .live() docs:

méthodes DOM traversal ne sont pas entièrement pris en charge pour trouver des éléments envoyer au .live(). Au contraire, la méthode .live() doit toujours être appelée directement après un sélecteur, comme dans l'exemple ci-dessus.

Vous appelez .live() sur un objet jQuery représentant un élément DOM particulier, au lieu vous devez obtenir les .selector les plugins en cours d'exécution sur, si il y a un, ce n'est pas garantie bien sûr, puis utilisez que pour .live, comme ceci:

jQuery.fn.sb_animateMenuItem = function() { 
    $(this.selector).live(.....) 

Si vous pensez, comment fait .live() travail? Il écoute l'événement à bulles, vérifie si la cible correspond un sélecteur, et exécute si c'est le cas (et dans un contexte, c'est une toute autre discussion) ... si vous avez fait $(DOMElement).live(), quel sélecteur vérifie-t-il pour voir si devrait exécuter?

Je suppose que vous pourriez dire basé sur l'élément interne UUID devrait travail, mais là encore c'est juste une .bind(), ce qui serait moins inutile, donc .live() ne fait pas quelque chose comme ça.


Mise à jour: Parce que je suis curieux de savoir la meilleure façon de mettre en œuvre ce sans code de répéter, voici une version de votre plugin qui choisit .live() ou .bind() dynamiquement, en fonction s'il y a un sélecteur présent pour .live() à utilisation:

jQuery.fn.sb_animateMenuItem = function() { 
    var mousehoverColor = '#0089F7'; 
    var duration = 250; 
    var method = this.selector ? jQuery.fn.live : jQuery.fn.bind; 
    method.apply(this, ['mouseover', function() { 
    if(!jQuery.data(this, 'oColor')) 
     jQuery.data(this, 'oColor', jQuery(this).css('background-color')); 
    jQuery(this).stop(true).animate({ backgroundColor:mousehoverColor }, duration); 
    }]); 
    method.apply(this, ['mouseout', function() { 
    jQuery(this).animate({ backgroundColor:jQuery.data(this, 'oColor') }, duration); 
    }]); 
    return this.css('cursor', 'pointer'); 
}; 

You can view a working demo showing both here.

+0

Un très grand +1. J'ai beaucoup appris de cette réponse. +1 à OP pour poser la question. – user113716

+0

Eh bien ... j'ai essayé dans les deux sens, mais ça ne marche toujours pas. J'ai décidé d'affronter le problème d'une autre manière: http://stackoverflow.com/questions/3032767/insert-html-into-a-page-with-ajax. – siannone

+0

@Silvio - Qu'est-ce qui ne fonctionne pas? J'ai fourni une démo montrant que cela fonctionne, vous devriez expliquer * ce qui ne fonctionne pas. Il est difficile de donner une solution lorsque vous ne connaissez pas le problème ... –

5

vous pouvez utiliser .DELEGATE() au lieu de .LIVE, .ON,.BIND

comme

$("body").DELEGATE($(this),"click","myfunction") 

OU

$("body").DELEGATE($(this),"click",function() { 
///code here 
}) 
+0

Merci, cela a fonctionné dans une instance avec le contenu ajouté dynamiquement ne se déclenche pas (s'avère que je faisais autre chose mal - en incorporant un formulaire dans un formulaire par erreur, mais il est intéressant de savoir à ce sujet). –

+0

J'espère que c'est mieux pour votre logique ... –