Jquery - привязать делегат ко всем тегам "a" - PullRequest
3 голосов
/ 13 октября 2011

Я пытаюсь заблокировать JQ click(), когда вы нажимаете на ссылку в div.

HTML

<div id="all">
    <div id="test">
        <a href="http://google.de">google</a>
    </div>
</div>

JS

$('#test').click(function() { alert('only when i click the div');  });

$('a').click(function(e) {
    e.stopPropagation();
    e.preventDefault();
    $('body').append(e.target.href);
});       

Этот код прекрасно работает, но мой контент динамически, поэтому мне нужноdelegate() решение.Код ниже не работает.Но почему?В чем проблема?

$('#all').delegate("a", "click", function(e)
{
    e.stopPropagation();
    e.preventDefault();
    $('body').append(e.target.href);
});

пример http://jsfiddle.net/Lf3hL/13/

Ответы [ 5 ]

5 голосов
/ 13 октября 2011

stopPropagation не работает с делегатом - http://api.jquery.com/event.stopPropagation/

Поскольку метод .live () обрабатывает события после того, как они распространены в верхнюю часть документа, невозможно остановить распространениеживых событий.Аналогично, события, обрабатываемые .delegate (), распространяются на элементы, которым они делегированы;обработчики событий, связанные с любыми элементами ниже этого в дереве DOM, уже будут выполнены к тому времени, когда будет вызван делегированный обработчик событий.Таким образом, эти обработчики могут предотвратить запуск делегированного обработчика, вызвав event.stopPropagation () или вернув false.

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

$('#all').delegate('#test', 'click' ,function() {
    alert('only when i click on the div');
});    

$('#all').delegate("a", "click", function(e)
{
    e.stopImmediatePropagation();
    e.preventDefault();
    $('body').append(e.target.href);
}); 

http://jsfiddle.net/Lf3hL/14/

2 голосов
/ 13 октября 2011

Поскольку delegate() работает, позволяя событиям всплывать, а затем обрабатывать их на элементе-предке (#all в вашем примере).

Итак, поскольку события уже всплыли, вы не можетеостановить их распространение в их источнике (потому что они должны распространяться на работу).

1 голос
/ 13 октября 2011

Из jQuery .delegate() doc :

Поскольку метод .live () обрабатывает события после их распространения в начало документа, это невозможноостановить распространение живых событий.Аналогично, события, обрабатываемые .delegate (), распространяются на элементы, которым они делегированы;Обработчики событий, привязанные к любым элементам ниже его в дереве DOM, будут уже выполнены к тому времени, когда будет вызван делегированный обработчик событий.

Одно из возможных решений - не подключать обработчик событий к a, но вместо этого #test и проверяя event.target.

Я обновил вашу скрипку этим методом.

   $('#test').click(function(e) {
        if ($(e.target).is('a')) {
            alert('link was clicked');
        }
        else {
            alert('only when i click on the div');
        }

        e.preventDefault(); //just to cancel the link's default action
    });
0 голосов
/ 13 октября 2011

Живые функции и функции делегата не могут обрабатывать вызов e.stopPropagation(); так же, как обычные события.Из делегата docs -

Поскольку метод .live () обрабатывает события после их распространения в верхней части документа, невозможно остановить распространение живых событий.,Аналогично, события, обрабатываемые .delegate (), распространяются на элементы, которым они делегированы;обработчики событий, связанные с любыми элементами ниже этого в дереве DOM, уже будут выполнены к тому времени, когда будет вызван делегированный обработчик событий.Таким образом, эти обработчики могут предотвратить запуск делегированного обработчика, вызвав event.stopPropagation () или вернув false.

0 голосов
/ 13 октября 2011

почему бы не использовать

.live()

функция

 $('a').live('click', function() {
     // Live handler called.
 });

, которая добавит функцию щелчка ко всем тегам, которые добавляются после полной загрузки тела.

...