Est-il possible d'utiliser jQuery .on et hover?

331

J'en ai un <ul>qui est rempli de javascript après le chargement initial de la page. J'utilise actuellement .bindavec mouseoveret mouseout.

Le projet vient d'être mis à jour vers jQuery 1.7, j'ai donc la possibilité de l'utiliser .on, mais je n'arrive pas à le faire fonctionner hover. Est-il possible d'utiliser .onavec hover?

EDIT : Les éléments auxquels je suis lié sont chargés avec javascript après le chargement du document. C'est pourquoi j'utilise onet pas seulement hover.

Ryre
la source
3
D'après un commentaire ci-dessous - la prise en charge des événements de survol dans On () était obsolète dans jQuery 1.8 et supprimée dans jQuery 1.9 . Essayez avec une combinaison de mouseenteret mouseleave, comme suggéré par calebthebrewer.
SexyBeast

Réponses:

677

( Regardez la dernière modification de cette réponse si vous devez utiliser .on()des éléments remplis de JavaScript )

Utilisez ceci pour les éléments qui ne sont pas remplis en utilisant JavaScript:

$(".selector").on("mouseover", function () {
    //stuff to do on mouseover
});

.hover()a son propre gestionnaire: http://api.jquery.com/hover/

Si vous voulez faire plusieurs choses, enchaînez-les dans le .on()gestionnaire comme ceci:

$(".selector").on({
    mouseenter: function () {
        //stuff to do on mouse enter
    },
    mouseleave: function () {
        //stuff to do on mouse leave
    }
});

Selon les réponses fournies ci-dessous, vous pouvez utiliser hoveravec .on(), mais:

Bien que fortement déconseillé pour le nouveau code, vous pouvez voir le pseudo-événement-nom "hover" utilisé comme raccourci pour la chaîne "mouseenter mouseleave". Il attache un seul gestionnaire d'événements pour ces deux événements, et le gestionnaire doit examiner event.type pour déterminer si l'événement est mouseenter ou mouseleave. Ne confondez pas le pseudo-événement-nom "hover" avec la méthode .hover (), qui accepte une ou deux fonctions.

En outre, il n'y a aucun avantage en termes de performances à l'utiliser et c'est plus volumineux que d'utiliser simplement mouseenterou mouseleave. La réponse que j'ai fournie nécessite moins de code et est la bonne façon de réaliser quelque chose comme ça.

ÉDITER

Cela fait un moment que cette question n'a pas reçu de réponse et elle semble avoir gagné du terrain. Le code ci-dessus existe toujours, mais je voulais ajouter quelque chose à ma réponse d'origine.

Bien que je préfère utiliser mouseenteret mouseleave(m'aide à comprendre ce qui se passe dans le code) avec, .on()cela revient à écrire ce qui suit avechover()

$(".selector").hover(function () {
    //stuff to do on mouse enter
}, 
function () {
    //stuff to do on mouse leave
});

Étant donné que la question initiale a demandé comment ils pouvaient utiliser correctement on()avec hover(), je pensais que je corrigerais l'utilisation de on()et n'a pas trouvé nécessaire d'ajouter le hover()code au moment.

MODIFIER LE 11 DÉCEMBRE 2012

Certaines nouvelles réponses fournies ci-dessous expliquent comment cela .on()devrait fonctionner si la divquestion en question est remplie à l'aide de JavaScript. Par exemple, supposons que vous remplissiez un événement divutilisant jQuery .load(), comme ceci:

(function ($) {
    //append div to document body
    $('<div class="selector">Test</div>').appendTo(document.body);
}(jQuery));

Le code ci-dessus pour .on()ne tiendrait pas. Au lieu de cela, vous devez modifier légèrement votre code, comme ceci:

$(document).on({
    mouseenter: function () {
        //stuff to do on mouse enter
    },
    mouseleave: function () {
        //stuff to do on mouse leave
    }
}, ".selector"); //pass the element as an argument to .on

Ce code fonctionnera pour un élément rempli de JavaScript après qu'un .load()événement s'est produit. Remplacez simplement votre argument par le sélecteur approprié.

Sethen
la source
1
@Scott, veuillez noter que la réponse de JonMcIntosh ne répond pas à ma question car il n'utilise que la moitié de la fonctionnalité de survol.
Ryre
1
Cela ne fonctionne pas pour les éléments qui ont été ajoutés au DOM. Comme le souligne @Nik Chankov ci-dessous, voici l'utilisation correcte de .on () pour attacher plusieurs gestionnaires stackoverflow.com/questions/8608145/…
soupy1976
1
@ soupy1976 Modifié ma réponse, il prend désormais en compte les éléments renseignés avec JavaScript.
Sethen
1
@SethenMaleno - exactement, et votre .on()solution fonctionne en supprimant le pseudo-survol et en utilisant les vrais. J'aime le premier que vous avez illustré avec mouseenter / mouseleave +1 pour cela
Mark Schultheiss
1
Cette modification a changé mon vote d'un vote négatif à un vote positif, bien joué, Sethen, bien joué!
Sean Kendle
86

Aucune de ces solutions n'a fonctionné pour moi lors du survol des objets créés après le chargement du document en tant que demande de question. Je sais que cette question est ancienne mais j'ai une solution pour ceux qui cherchent toujours:

$("#container").on('mouseenter', '.selector', function() {
    //do something
});
$("#container").on('mouseleave', '.selector', function() {
    //do something
});

Cela liera les fonctions au sélecteur afin que les objets avec ce sélecteur créés après que le document soit prêt pourront toujours l'appeler.

cazzer
la source
5
Celui-ci a la bonne solution: stackoverflow.com/questions/8608145/…
Nik Chankov
C'est ainsi que je l'ai fait fonctionner aussi, j'ai trouvé la réponse acceptée en plaçant le sélecteur avant que le .on ne fonctionne pas après un événement .load () mais cela fonctionne.
MattP
@calebthebrewer Modifié ma réponse, il prend désormais en compte les éléments peuplés de JavaScript.
Sethen
5
L'utilisation des événements mouseoveret mouseoutici provoquera le déclenchement continu du code à mesure que l'utilisateur déplace la souris à l'intérieur de l'élément. Je pense mouseenteret je suis mouseleaveplus approprié car il ne se déclenchera qu'une fois à l'entrée.
johntrepreneur
1
l'utilisation du document comme élément racine n'est pas la meilleure pratique, car ses performances sont gourmandes. vous surveillez un document, tandis qu'avec load () vous ne manipulez la plupart du temps qu'une partie du site Web (f.ex. #content). il vaut donc mieux essayer de le réduire à l'élément, c'est manipulé ..
honk31
20

Je ne sais pas à quoi ressemble le reste de votre Javascript, donc je ne pourrai pas dire s'il y a une interférence. Mais .hover()fonctionne très bien comme un événement avec .on().

$("#foo").on("hover", function() {
  // disco
});

Si vous voulez pouvoir utiliser ses événements, utilisez l'objet retourné de l'événement:

$("#foo").on("hover", function(e) {
  if(e.type == "mouseenter") {
    console.log("over");
  }
  else if (e.type == "mouseleave") {
    console.log("out");
  }
});

http://jsfiddle.net/hmUPP/2/

Jon McIntosh
la source
Comment cela gère-t-il les fonctions distinctes d'activation / désactivation que le survol utilise? Ex: $('#id').hover(function(){ //on }, function(){ //off});
Ryre
Pour moi, ce n'est pas nécessaire .. Vous n'avez pas besoin d'utiliser .on()avec hoverquand vous pouvez tout aussi bien vous en débarrasser .on()et le remplacer par la .hover()fonction et obtenir les mêmes résultats. N'est-ce pas jQuery d'écrire moins de code ??
Sethen
@Toast it does not, see my answer below to see how to perform mouseenterand mouseleavefonctionne with.on()
Sethen
J'ai mis à jour ma réponse pour inclure l'utilisation des deux types d'événements. Cela fonctionne de la même manière que la réponse de Sethen mais a une saveur différente.
Jon McIntosh
24
hoverla prise en charge des événements dans a On()été déconseillée dans jQuery 1.8 et supprimée dans jQuery 1.9.
Fin du codage le
9

La fonction de survol de jQuery offre des fonctionnalités de survol et de sortie de souris.

$ (sélecteur) .hover (inFunction, outFunction);

$(".item-image").hover(function () {
    // mouseover event codes...
}, function () {
    // mouseout event codes...
});

Source: http://www.w3schools.com/jquery/event_hover.asp

Tigin
la source
3
fonctionne certainement. vous avez obtenu un vote vers le bas parce que certaines personnes sont vides! Merci compagnon
Kareem
8

Je viens de surfer sur le Web et j'ai senti que je pouvais contribuer. J'ai remarqué qu'avec le code ci-dessus publié par @calethebrewer peut entraîner plusieurs appels sur le sélecteur et un comportement inattendu par exemple: -

$(document).on('mouseover', '.selector', function() {
   //do something
});
$(document).on('mouseout', '.selector', function() {
   //do something
});

Ce violon http://jsfiddle.net/TWskH/12/ illustre mon propos. Lors de l'animation d'éléments tels que des plugins, j'ai constaté que ces déclencheurs multiples entraînent un comportement involontaire qui peut entraîner l'animation ou le code appelé plus qu'il n'est nécessaire.

Ma suggestion est de simplement remplacer par mouseenter / mouseleave: -

$(document).on('mouseenter', '.selector', function() {
   //do something
});
$(document).on('mouseleave', '.selector', function() {
   //do something
});

Bien que cela ait empêché d'appeler plusieurs instances de mon animation, j'ai finalement opté pour le survol de la souris / souris car je devais déterminer quand les enfants du parent étaient survolés.

KryptoniteDove
la source
Cette réponse a en fait fourni une solution de travail pour ajouter un événement de survol pour un sélecteur de document. +1
Rich Davis
5

Vous pouvez l'utiliser .on()avec hoverce que dit la section Notes supplémentaires:

Bien que fortement déconseillé pour le nouveau code, vous pouvez voir le pseudo-événement-nom "hover" utilisé comme raccourci pour la chaîne "mouseenter mouseleave". Il attache un seul gestionnaire d'événements pour ces deux événements, et le gestionnaire doit examiner event.type pour déterminer si l'événement est mouseenter ou mouseleave. Ne confondez pas le pseudo-événement-nom "hover" avec la méthode .hover (), qui accepte une ou deux fonctions.

Ce serait de faire ce qui suit:

$("#foo").on("hover", function(e) {

    if (e.type === "mouseenter") { console.log("enter"); }
    else if (e.type === "mouseleave") { console.log("leave"); }

});

EDIT (note pour les utilisateurs de jQuery 1.8+):

Déconseillé dans jQuery 1.8, supprimé dans 1.9: Le nom "hover" utilisé comme raccourci pour la chaîne "mouseenter mouseleave". Il attache un seul gestionnaire d'événements pour ces deux événements, et le gestionnaire doit examiner event.type pour déterminer si l'événement est mouseenter ou mouseleave. Ne confondez pas le pseudo-événement-nom "hover" avec la méthode .hover (), qui accepte une ou deux fonctions.

Code Maverick
la source
1
C'est juste plus de travail quand cela peut facilement être fait en utilisant mouseenteret mouseleave... Je sais, cela ne répond pas à la question d'origine d'OP, mais, en utilisant hoverde cette façon, ce n'est pas sage.
Sethen
Le faire de cette façon suit exactement comment l'équipe jQuery vous suggère de le faire conformément à la question du PO. Cependant, comme le suggère l'équipe jQuery, il est fortement déconseillé d'utiliser un nouveau code. Mais, c'est toujours la bonne réponse à la question du PO.
Code Maverick
1
@Scott - vous étiez plus rapide que moi :-). @Sethen - les deux méthodes fonctionneront, mais le demandeur a demandé la fonctionnalité avec .hover().
Jon McIntosh
Naturellement, mais je pense que OP recherchait une solution pour un mouseenteret mouseleaveplutôt que de simplement le faire fonctionner hover. S'il n'y a pas vraiment de raison d'utiliser hoverpour des raisons de performances, pourquoi l'utiliser quand il est fortement déconseillé pour le nouveau code?
Sethen
5
hoverla prise en charge des événements dans a On()été déconseillée dans jQuery 1.8 et supprimée dans jQuery 1.9.
Fin du codage le
5
$("#MyTableData").on({

 mouseenter: function(){

    //stuff to do on mouse enter
    $(this).css({'color':'red'});

},
mouseleave: function () {
    //stuff to do on mouse leave
    $(this).css({'color':'blue'});

}},'tr');
webmaster01
la source
2

Vous pouvez fournir un ou plusieurs types d'événements séparés par un espace.

Donc, c'est hoverégal mouseenter mouseleave.

Voici ma suggestion:

$("#foo").on("mouseenter mouseleave", function() {
    // do some stuff
});
user2386291
la source
J'aime la décision de jQ de déprécier ce paramètre. Avant la version 1.8, utiliser pour survoler comme espace de noms ne coïncidait pas avec l'événement DOM, survoler, aucune relation.
Jim22150
1

Si vous en avez besoin comme condition dans un autre événement, je l'ai résolu de cette façon:

$('.classname').hover(
     function(){$(this).data('hover',true);},
     function(){$(this).data('hover',false);}
);

Ensuite, dans un autre événement, vous pouvez facilement l'utiliser:

 if ($(this).data('hover')){
      //...
 }

(J'en vois certains utiliser is(':hover')pour résoudre ce problème. Mais ce n'est pas (encore) un sélecteur jQuery valide et ne fonctionne pas dans tous les navigateurs compatibles)

Sanne
la source
-2

Le plugin jQuery hoverIntent http://cherne.net/brian/resources/jquery.hoverIntent.html va beaucoup plus loin que les approches naïves répertoriées ici. Bien qu'ils fonctionnent certainement, ils ne se comportent pas nécessairement comme les utilisateurs les attendent.

La principale raison d'utiliser hoverIntent est la fonction de délai d' expiration . Cela vous permet de faire des choses comme empêcher un menu de se fermer parce qu'un utilisateur fait glisser sa souris légèrement trop loin vers la droite ou la gauche avant de cliquer sur l'élément qu'il souhaite. Il fournit également des capacités pour ne pas activer les événements de vol stationnaire dans un barrage et attend le vol stationnaire concentré.

Exemple d'utilisation:

var config = {    
 sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)    
 interval: 200, // number = milliseconds for onMouseOver polling interval    
 over: makeTall, // function = onMouseOver callback (REQUIRED)    
 timeout: 500, // number = milliseconds delay before onMouseOut    
 out: makeShort // function = onMouseOut callback (REQUIRED)
};
$("#demo3 li").hoverIntent( config )

De plus amples explications sont disponibles sur https://stackoverflow.com/a/1089381/37055

Chris Marisic
la source