jQuery - запускати події в прямому ефірі лише один раз на елемент на сторінці?

Ось сценарій

$("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()?
    }
})

Ось якийсь фон

The custom event is from a plugin called inview

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

  1. Одним словом, нові повідомлення tumblr прокручуються по інклюзії Хакка з JavaScript (єдиний там для tumblr fyi).
  2. Плагін перегляду прослуховує нові публікації, які з'являються у вікні перегляду, якщо верхній частині зображення відображається, він стає видимим.
  3. Це працює, але якщо ви перевіряєте консоль на http: //.syndex.me , перевірте, як часто подія звільняється
  4. Може бути, я теж буду метушливий, і це нормально? Будь ласка, дайте мені знати свою професійну думку. але в ідеалі я хотів би, щоб вона перестала робити те, що мені більше не потрібна.

Деякі речі, які я пробував, не працювали:

  1. stopPropagation

  2. .die ();

  3. Деякі рішення через S.O. не працював, наприклад, У jQuery є чи можна спочатку пов'язувати лише один клік? або Використання .one() з. Live() jQuery

Я дуже здивований, чому такий варіант ще не існує. Звичайно, подію .one() теж потрібні і для майбутніх елементів? #просто говорю

Дякую.

1

3 Відповіді

Додайте клас до елемента, коли трапляється подію, і трапляється лише те, що відбувається в елементах, у яких немає такого класу.

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

Редагувати: приклад з коментарів:

$("p").live(event,function(){
  var $this = $(this);
  if ($this.data("live")) {
    return;
  }
  $this.data("live",true);
  doStuff();
});
2
додано
Відмінна ідея Кевіна; звичайно, функціональний :) Я почав ухилятися від використання тегів CSS на користь об'єкта даних; Мені просто не подобається повторювати десанти CSS, що може завадити нам, якщо "nolive" (у цьому випадку) коли-небудь опинився в таблиці стилів. Їжа для роздумів.
додано Автор Kato, джерело
Правда, правда ... програмування - це все про компроміси, чи не так? :)
додано Автор Kato, джерело
Що таке $ this = $ (це) потрібно?
додано Автор RGBK, джерело
Дякую за відгук. Важко вибрати √ тут, вони все гарні. Я вибрав цей варіант, оскільки має два варіанти. Ви не знаєте, скільки публікацій dud SO, які я створив за останні 24 годин, щоб отримати правильне запитання. Дякую всім вам.
додано Автор RGBK, джерело
Єдина проблема з використанням об'єкта даних полягає в тому, що її не можна фільтрувати за допомогою простого селектора, такого як це. Ви в кінцевому підсумку матиме лише такий вислів, як у вас. Я покажу приклад.
додано Автор Kevin B, джерело
Оскільки ми використовуємо $ (цей) кілька разів, я кешував його, щоб зменшити необхідну обробку. Це не вимагається і не має значення у цьому випадку, це лише те, що я звик робити кожен раз, коли я використовую один і той же вибір більше одного разу.
додано Автор Kevin B, джерело

Це працює (див. Розділ скрип ).

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}); });

Це також повинно працювати для ваших потреб, хоча це не так добре :)

$("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
додано

Як згадував Кевін, ви можете виконати це, маніпулюючи селекторами CSS, але вам насправді не потрібно використовувати : not() . Ось альтернативний метод:

// 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")
   }
});

Я використовував фактичний код із вашого сайту. Сподіваюся, це все гаразд.

1
додано