JQuery stopPropagation на .live(), когда обработчики уже существуют

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

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

использование .click() в сочетании с eventStopPropagation() работает просто отлично, однако из-за динамического характера контента мне нужно использовать либо live, on, delegate и т. д. Вот скрипка моей проблемы. Мне нужно предотвратить срабатывание «среднего» щелчка при нажатии на «внутренний» div. Я не могу не изменить "средний" обработчик (это лучше, если учесть, что у меня даже нет к нему доступа).

Заранее спасибо за помощь!! И извините за повтор, я думал, что так будет аккуратнее.

http://jsfiddle.net/99zQM/9/

HTML:

<div id="outer">
    outer non dynamic element
    <div id="middle">
        middle dynamic
        <div id="inner">
            inner dynamic
        </div>
    </div>
</div>

Javascript:

$("#middle").bind('click',function(e){
    //is rebound when content is loaded
   alert("middle clicked"); 
});
$('#inner').live('click',function(e){
    alert("inner clicked"); 
});

person Pomme.Verte    schedule 05.03.2013    source источник
comment
... которые связывают элементы ...?   -  person Beetroot-Beetroot    schedule 05.03.2013
comment
@FrédéricHamidi Привет, я чувствовал, что это несправедливо по отношению к тем, кто уже ответил правильно. Это совсем другая проблема. Однако я не обращаю внимания на руководство по поведению stackoverflow, поэтому я могу ошибаться, делая что-то таким образом.   -  person Pomme.Verte    schedule 05.03.2013
comment
@Beetroot-Beetroot Это привязывает обработчики событий к элементам, мой плохой, я отредактирую   -  person Pomme.Verte    schedule 05.03.2013


Ответы (3)


Используйте этот код

$(document).bind('click',function(e) {
    if (e.target)
        target = e.target;
    else if (e.srcElement)
        target = e.srcElement;
    else
        target = e.currentTarget;

    if (target.id == 'middle') 
    {
    alert("middle clicked"); 
    }

       else if (target.id == 'inner')
       {
       alert("inner clicked"); 
       }
});

http://jsfiddle.net/99zQM/12/

person supersaiyan    schedule 05.03.2013
comment
не самые чистые, но отчаянные времена требуют решительных мер. В настоящее время я использую это, поэтому я определенно голосую за него. В моем конкретном случае я применил эту концепцию к событию среднего щелчка (хотя я сказал, что не хочу касаться этого в своем вопросе). Если ничего лучше не появится, я отмечу это как правильный ответ - person Pomme.Verte; 05.03.2013

Вы должны использовать .on для привязки события клика. Для каждой привязки к #outer, #middle и #inner. Используйте stopPropagation, чтобы предотвратить всплывающее событие.

$("#outer").on('click', function(e){
    e.stopPropagation();
    alert("outer clicked"); 
});

$("#outer").on('click', '#middle', function(e){
    e.stopPropagation();
    alert("middle clicked"); 
});

$("#outer #middle").on('click', '#inner', function(e){
    e.stopPropagation();
    alert("inner clicked"); 
});

Пример jsFiddle: http://jsfiddle.net/99zQM/11/

person Derek    schedule 05.03.2013
comment
к сожалению, в моем случае из реальной жизни есть еще несколько уровней, на некоторых из которых есть события, которые нужно всплывать. - person Pomme.Verte; 05.03.2013

Вы можете попытаться захватить обработчик кликов и динамически обернуть его в другой обработчик, который проверяет всплывающие окна событий следующим образом:

// Your code does not change

    $("#middle").bind('click',function(e){
        //is rebound when content is loaded
       alert("middle clicked"); 
    });

    $('#inner').live('click',function(e){
        alert("inner clicked"); 
    });

// capture the click handler on #middle and wrap it inside a test for bubbling
var handler = $._data($("#middle")[0], "events")["click"][0].handler;
$('#middle').unbind('click');

$("#middle").bind('click',(function(handlerVar){return function(e){
    if(e.target===this) // test for bubbling
    {
        handlerVar(e);
    }
}})(handler));

см.: http://jsfiddle.net/99zQM/13/

Надеюсь, это поможет

person jbl    schedule 05.03.2013
comment
Мне это очень нравится, но если я динамически удалю и перезагружу #middle, это больше не будет работать? Или я что-то упускаю? Я хотел бы найти способ реализовать это на динамическом контенте. - person Pomme.Verte; 05.03.2013
comment
@D.Mill Вам придется выполнять этот код после каждой привязки клика к #middle. Но вы могли бы обернуть его в функцию, которую вы могли бы вызвать сразу после вызова щелчка привязки, который, я полагаю, все еще будет там. - person jbl; 05.03.2013