Jquery, événement de reliure de la molette de la souris, puis sa réassociation une fois les actions terminées?

Cela fait quelque temps que je lutte avec cela. J’utilise ce code pour surveiller la molette de la souris afin qu’il puisse être utilisé pour le défilement avec un curseur que j’ai .. Cependant, il y a un problème où les actions se mettent en queue afin Si vous faites défiler rapidement avec la molette de la souris (comme tout le monde le ferait normalement), ils s’accumulent et provoquent un comportement buggy. Je sais comment gérer ce type de problème avec une animation, mais pas avec un moniteur de molette.

Je veux faire quelque chose comme lier la molette au début de l’action (dans ce cas, faire défiler la barre de défilement après avoir déplacé la molette), puis la lier de nouveau après cela. scroll est terminé .. J’ai essayé le code ci-dessous mais ce n’est pas un rappel, donc je ne suis pas sûr de ce que je fais mal, tout conseil est apprécié.

$("#wavetextcontainer").bind("mousewheel", function(event, delta) { //HERE IS WHERE EVENT IS UNBOUND: $("#wavetextcontainer").unbind("mousewheel"); var speed = 10; var mySlider = $("#slider"); var sliderVal = mySlider.slider("option", "value"); sliderVal += (delta*speed); if (sliderVal > mySlider.slider("option", "max")) sliderVal = mySlider.slider("option", "max"); else if (sliderVal < mySlider.slider("option", "min")) sliderVal = mySlider.slider("option", "min"); $("#slider").slider("value", sliderVal); event.preventDefault(); // HERE I WANT TO REBIND THE EVENT: $("#wavetextcontainer").bind("mousewheel"); }); 

Vous devez stocker la fonction où vous pouvez la référencer, comme ceci:

 function myHandler(event, delta) { $("#wavetextcontainer").unbind("mousewheel", myHandler); var speed = 10; var mySlider = $("#slider"); var sliderVal = mySlider.slider("option", "value"); sliderVal += (delta*speed); if (sliderVal > mySlider.slider("option", "max")) sliderVal = mySlider.slider("option", "max"); else if (sliderVal < mySlider.slider("option", "min")) sliderVal = mySlider.slider("option", "min"); $("#slider").slider("value", sliderVal); event.preventDefault(); // HERE I WANT TO REBIND THE EVENT: $("#wavetextcontainer").bind("mousewheel", myHandler); }; $("#wavetextcontainer").bind("mousewheel", myHandler); 

En faisant cela, vous pouvez appeler .bind() ultérieurement à la même fonction (vous ne pouvez pas référencer une fonction anonyme). Vous essayez actuellement d'appeler .bind() sans une fonction pour gérer quoi que ce soit, ce qui ne fonctionne pas. Cela présente également l’avantage supplémentaire de pouvoir transmettre la même référence de fonction à .unbind() sorte qu’il ne lie pas uniquement ce gestionnaire, ni aucun gestionnaire de mousewheel .


Sinon, faites ceci sans un / re-binding, comme ceci:

 $("#wavetextcontainer").bind("mousewheel", function (event, delta) { event.preventDefault(); if($.data(this, 'processing')) return; //we're processing, ignore event $.data(this, 'processing', true); var speed = 10; var mySlider = $("#slider"); var sliderVal = mySlider.slider("option", "value"); sliderVal += (delta*speed); if (sliderVal > mySlider.slider("option", "max")) sliderVal = mySlider.slider("option", "max"); else if (sliderVal < mySlider.slider("option", "min")) sliderVal = mySlider.slider("option", "min"); $("#slider").slider("value", sliderVal); $.data(this, 'processing', false); }); 

Cela utilise simplement $.data() pour stocker une entrée de données "Nous travaillons" avec l'élément. Si quelque chose frappe ce gestionnaire alors qu'il est vrai, il renvoie et ignore l'événement.

Dans cette situation, il y a beaucoup de liaisons inutiles, ce qui est plus difficile et plus inefficace que nécessaire. La suppression de la reliure est excellente pour libérer des ressources lorsqu’une action n’est plus nécessaire ou ne sera plus nécessaire pendant un certain temps; mais pour une fraction de seconde de ne pas vouloir que votre code s’exécute sans être lié / lié, utilisez simplement une variable pour déterminer si vous souhaitez respecter la molette de la souris ou non, et basculez-le simplement sur true ou faux si nécessaire. Probablement pas besoin d’utiliser les données jquery non plus, juste une variable plus rapide définie en dehors de la fonction.

 var doMouseWheel = true; $("#wavetextcontainer").bind("mousewheel", function(event, delta) { // it'll just not do anything while it's false if (!doMouseWheel) return; // here's where you were unbinding, now just turning false doMouseWheel = false; // do whatever else you wanted // here's where you were rebinding, now just turn true doMouseWheel = true; }); 

Honnêtement, bien que la logique de désactiver le scroller alors que les quelques lignes ci-dessus traitent soit un peu défectueuse, vous devez être un programmeur qui a beaucoup traité avec les langages multithreading 🙂 les lignes de code de la fonction, donc je suppose que vous préféreriez l’éteindre pendant un certain temps (et cela s’appliquerait que vous utilisiez une variable ou un lien / un-lien):

 var doMouseWheel = true; $("#wavetextcontainer").bind("mousewheel", function(event, delta) { // it'll just not do anything while it's false if (!doMouseWheel) return; // here's where you were unbinding, now just turning false doMouseWheel = false; // do whatever else you wanted // here's where you were rebinding, now wait 200ms and turn on setTimeout(turnWheelBackOn, 200); }); function turnWheelBackOn() { doMouseWheel = true; }