jQuery - activeer slechts één keer een live-evenement per element op de pagina?

Dit is het scenario

$("p").live('customEvent', function (event, chkSomething){ 
//this particular custom event works with live
    if(chkSomething){
        doStuff();
       //BUT only per element
       //So almost like a .one(), but on an elemental basis, and .live()?
    }
})

Hier is wat achtergrond

The custom event is from a plugin called inview

The actual issue is here http://syndex.me

  1. Kort samengevat, er worden nieuwe tumblr-posts met grote regelmaat doorgeschoven javascript hack (de enige die er is voor tumblr fyi.)
  2. De inview-plug-in luistert naar nieuwe berichten die in het kijkvenster komen. Als de bovenkant van een afbeelding wordt weergegeven, wordt deze zichtbaar.
  3. Het werkt een beetje, maar als u uw console controleert op http: //.syndex.me , controleert u hoe vaak het evenement wordt afgevuurd
  4. Misschien ben ik ook te kieskeurig en dit is goed? Laat me je professionele mening weten. maar idealiter zou ik het leuk vinden om iets te doen dat ik niet meer nodig heb.

Sommige dingen die ik heb geprobeerd, werkten niet:

  1. stopPropagation

  2. .die ();

  3. Sommige oplossingen via S.O. werkte ook niet, bijvoorbeeld In jQuery, is is er een manier om slechts één keer een klik te binden? of .one() gebruiken met. live() jQuery

Ik ben behoorlijk verbaasd waarom zo'n optie er nog niet is. Zeker, de .one() -gebeurtenis is ook nodig voor toekomstige elementen? #ik bedoel maar

Bedankt.

1

3 antwoord

Voeg een klasse toe aan het element wanneer de gebeurtenis plaatsvindt en laat de gebeurtenis alleen plaatsvinden op elementen die die klasse niet hebben.

$("p:not(.nolive)").live(event,function(){
  $(this).addClass("nolive");
  dostuff();
});

Bewerken: Voorbeeld van opmerkingen:

$("p").live(event,function(){
  var $this = $(this);
  if ($this.data("live")) {
    return;
  }
  $this.data("live",true);
  doStuff();
});
2
toegevoegd
Geweldig idee Kevin; zeker functioneel :) Ik ben begonnen weg te gaan van het gebruik van css-tags in het voordeel van het data-object; Ik vind het gewoon niet leuk om css-declaraties opnieuw te gebruiken, waardoor we in de problemen kunnen komen als 'nolive' (in dit geval) ooit in de stylesheet terecht is gekomen. Stof tot nadenken.
toegevoegd de auteur Kato, de bron
Waar, waar ... programmeren draait allemaal om compromissen, nietwaar? :)
toegevoegd de auteur Kato, de bron
Waar is de $ this = $ (dit) voor nodig?
toegevoegd de auteur RGBK, de bron
Leuk bedankt voor de tip. Het is moeilijk om hier een √ te kiezen, ze zijn allemaal goed. Ik koos deze omdat er twee opties zijn. Je hebt geen idee hoeveel idioot ik berichten die ik in de afgelopen 24 uur heb gemaakt om de juiste vraag te formuleren. Mijn dank aan jullie allemaal.
toegevoegd de auteur RGBK, de bron
Het enige probleem met het gebruik van een data-object is dat het niet kan worden gefilterd met behulp van een eenvoudige selector zoals deze. Je zou alleen een if-statement krijgen zoals je hebt. Ik zal een voorbeeld maken.
toegevoegd de auteur Kevin B, de bron
Omdat we $ (this) meer dan eens gebruiken, heb ik deze in de cache opgeslagen om de vereiste verwerking te verminderen. Het is niet verplicht en maakt in dit geval geen verschil, het is gewoon iets waar ik aan gewend ben geraakt elke keer als ik dezelfde selectie meer dan eens gebruik.
toegevoegd de auteur Kevin B, de bron

Deze werkt (zie fiddle ):

jQuery(function($) {
    $("p").live('customEvent', function(event, chkSomething) {
        //this particular custom event works with live
        if (chkSomething) {
            doStuff();
           //BUT only per element
           //So almost like a .one(), but on an elemental basis, and .live()?
            $(this).bind('customEvent', false);
        }
    });

    function doStuff() {
        window.alert('ran dostuff');
    };

    $('#content').append('
Here is a test

'); $('p').trigger('customEvent', {one: true}); $('p').trigger('customEvent', {one: true}); $('p').trigger('customEvent', {one: true}); });

Dit zou ook moeten werken voor uw behoeften, hoewel het niet zo mooi is :)

$("p").live('customEvent', function (event, chkSomething){ 
    //this particular custom event works with live
    if(chkSomething && $(this).data('customEventRanAlready') != 1){
        doStuff();
       //BUT only per element
       //So almost like a .one(), but on an elemental basis, and .live()?
        $(this).data('customEventRanAlready', 1);
    }
})
1
toegevoegd

Zoals Kevin al zei, kun je dit bereiken door de CSS-selectors te manipuleren, maar je hoeft eigenlijk geen : not() te gebruiken. Hier is een alternatieve methode:

// Use an attribute selector like so. This will only select elements
// that have 'theImage' as their ONLY class. Adding another class to them
// will effectively disable the repeating calls from live()
$('div[class=theImage]').live('inview',function(event, visible, visiblePartX, visiblePartY) {
   if (visiblePartY=="top") {
      $(this).animate({ opacity: 1 });
      $(this).addClass('nolive');
      console.log("look just how many times this is firing")
   }
});

Ik heb de eigenlijke code van uw site gebruikt. Ik hoop dat het goed was.

1
toegevoegd