Реализация jQuery Live в прототипе

Element.implement({
    addLiveEvent: function(event, selector, fn){
        this.addEvent(event, function(e){
            var t = $(e.target);

            if (!t.match(selector)) return false;
                fn.apply(t, [e]);
        }.bindWithEvent(this, selector, fn));
    }
});

$(document.body).addLiveEvent('click', 'a', function(e){ alert('This is a live event'); });

Приведенный выше код был выполнен в похожем вопросе реализовать поведение .live в Mootools. Я прочитал вопрос: эквивалент прототипа для живой функции jQuery.

Как реализовать это в прототипе? Вероятно, что-то, что можно реализовать так:

document.liveobserve('click', 'a', function(e){ alert('This is a live event');

Отредактировано, чтобы прояснить вопрос.


person Teej    schedule 05.03.2010    source источник
comment
Честно говоря, в mootools (хотя в текущем релизе это шатко) теперь работает нативно/по-другому, например: $('foo').addEvent('click:relay(li)'); - хотя не уверен, что это поможет с прототипом.   -  person Dimitar Christoff    schedule 05.03.2010
comment
@Димитар. приятно знать +1   -  person Teej    schedule 05.03.2010


Ответы (1)


Самый простой (и, возможно, не самый быстрый или лучший) способ выглядит примерно так:

Element.live = function(evType, evSelector, evBlock) {
  var mySelector = evSelector;
  var myBlock = evBlock;
  this.observe(evType, function(ev) {
    if (ev.target.match(mySelector)) {
      evBlock(ev);
    }
  });
};

Параметры evSelector и evBlock назначаются локальным переменным, поэтому они доступны обработчику событий (это замыкание). Переданный блок evBlock получает объект события, как обычный обработчик событий Prototype.

Следует отметить, что это будет обрабатывать каждое событие типа 'evType', поэтому, если это mouseMove/mouseOver, это замедлит работу вашей страницы. Кроме того, FireBug, вероятно, просто заснет из-за количества событий, которые он должен пройти за один шаг.

РЕДАКТИРОВАТЬ: изменено в соответствии с комментариями

person Haqa    schedule 26.06.2011
comment
Я считаю, что этот код не требует, чтобы элемент, для которого срабатывает событие, был потомком того, для которого было вызвано .live, что делает jQuery. Вы только проверяете, соответствуют ли цели события evSelector, а также должны проверять, является ли оно потомком self (установите значение this во внешней функции, поскольку вызов наблюдения больше не будет иметь тот же связанный объект). - person Gijs; 26.06.2011
comment
Хороший вопрос, но выполнение наблюдения за этим вместо документа должно решить эту проблему, не так ли? - person Haqa; 26.06.2011