Есть ли способ делегировать событие один в jQuery? - PullRequest
2 голосов
/ 29 июля 2011

Я бы хотел делегировать событие один для клика . Кто-нибудь знает, возможно ли это сделать?

Ответы [ 3 ]

8 голосов
/ 29 июля 2011

Я собираюсь предположить, что вы хотите, чтобы событие вызывалось только один раз, когда элемент соответствовал PER, а не полностью отменял привязку при первом щелчке.

Я бы реализовал это так:

$('#container').delegate('.children', 'click', function() {
  if($(this).data('clicked')) {
      return;
  }

  // ... your code here ...


  $(this).data('clicked', true);

});

Это будет срабатывать только один раз за элемент. Технически, он срабатывает каждый раз, но помечается при первом нажатии, чтобы код больше не выполнялся.

Внутренняя проблема моделирования обработчика .one () с делегатом заключается в том, что при использовании .one () каждый элемент, который был сопоставлен в селекторе, связывается со своим собственным обработчиком событий. Поэтому, когда он запускается впервые, он освобождает / удаляет обработчик из этого элемента. Вы не можете сделать это с помощью .delegate (), потому что для ВСЕХ соответствующих элементов используется только ОДИН обработчик.

Хотя приведенный выше код полностью имитирует его, он все же несколько хакерский, потому что он буквально не делает того же, что и .one () (отменяет привязку обработчика события).

2 голосов
/ 28 мая 2015

Поскольку этому посту несколько лет, я просто хотел предоставить полностью обновленный пример для более современных читателей (2015). Логика не отличается от других ответов здесь, но методы jQuery развивались с 2011 года. В частности:

Начиная с jQuery 1.7, метод .delegate () был заменен методом .on ().
jQuery делегат ()

// define output element
var $output = $('div#output');

// attach delegated click handler
$(document).on('click', 'button', function() {
  
  // define clicked element
  var $this=$(this);
  
  // if this element has already been clicked, abort
  if ($this.data('clicked')) {
    return false;
  }
   
  // perform click actions
  $output.append("clicked " + $this.html() + "<br />");
 
  // mark this element as clicked
  $this.data('clicked',true);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button>One</button>
<button>Two</button>
<button>Three</button>

<div id="output"></div>
1 голос
/ 29 июля 2011

Я уверен, что есть изящный способ сделать это, но простой способ сделать это будет примерно так:

<script>
  $(document).ready(function(){
    $("#container").delegate('.clickers', 'click', function(){
      if($(this).data("clicked")==null){
        $(this).data("clicked", "true");
        $("#container").append($(this).html());
      }
    });
  });
</script>
<div class="clickers" clicked="false"></div>
<div class="clickers" clicked="false"></div>

РЕДАКТИРОВАТЬ: Благодаря комментариям ниже я решил использовать данные, теперь это не испортит DOM для стандартов w3c.

...