jQuery, как выполнить событие только для внутреннего элемента

Есть ли способ позволить что-то делать только внутреннему элементу listitem?

У меня есть элементы списка, которые могут содержать теги a с определенным классом.

Внутренние теги a привязаны к обработчику события клика в реальном времени. Сами элементы списка также имеют обработчик события щелчка.

Что-то вроде этого

<li>some text<a class="someClassName">some text</a></li>

с обработчиком тегов a

$('#somelist li a').live("click", function(e)

и вот как добавляется событие для элемента li

$(markers).each(function(i,marker){
    $("<li />") 
    .html("Locatie "+'<a class="ol id"><strong>'+ids[i]+'</strong></a>') 
    .click(function(e){
          showLocation(marker, i);
    })
    .appendTo("#somelist ");

person Richard    schedule 23.02.2010    source источник
comment
Не могли бы вы опубликовать больше кода? Что динамически добавляется? И a, и li? Только a? Щелчок для li использует bind(), а a использует live()?   -  person user113716    schedule 23.02.2010
comment
Элементы li динамически добавляются в начале. На более позднем этапе, когда установлен флажок, к элементам списка добавляется дополнительный тег a. Я проверяю с помощью hasClass, какой из них нажат. Думаю, у меня есть привязка и живое событие, тогда   -  person Richard    schedule 24.02.2010
comment
Хорошо, вы говорите, что я должен постоянно использовать live. Я могу определенно попробовать это, а также попробовать решение от @Alex. Я могу вернуться позже, чтобы проверить, сработало ли одно, другое или оба. Спасибо вам обоим за ценный вклад.   -  person Richard    schedule 24.02.2010
comment
Алекс предложил ключ к отличному решению. Пожалуйста, посмотрите его ответ.   -  person user113716    schedule 24.02.2010
comment
Вы должны быть осторожны с использованием «return false». Вместо этого используйте e.preventDefault или e.stopPropogation.   -  person Paul Sullivan    schedule 15.07.2012


Ответы (3)


Метод live в jQuery работает через делегирование событий, то есть перехватывает все всплывающие события из отдельных элементов на общего предка (в вашем случае это document).

Остановка распространения/пузырькового события щелчка происходит в элементе обработчика (который является общим предком, а не в самом элементе) и существует намного выше li, которого вы пытаетесь избежать.

Таким образом, к моменту вызова метода stopPropagation мы уже прошли по dom и передали элемент li.

По сути, это установка знака «Стоп» в 200 футах после перекрестка.

Поэтому вам нужно либо использовать bind и stopPropagation, либо найти другое решение.

Вот пример того, о чем я говорю: http://jsbin.com/iuxo (проверьте приставка)

вы можете увидеть код или отредактировать его по адресу http://jsbin.com/iuxo/edit.

Мое предлагаемое решение этой проблемы состояло бы в том, чтобы использовать bind вместо live.

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

Вероятно, вы используете live, потому что добавляете новые элементы и хотите, чтобы они имели ту же функциональность. Вы должны сделать это, привязав их, когда вводите их на страницу. Вот пример

$(function(){
  var myAnchorHandler = function(e){
    alert('clicked!');
    e.stopPropagation();
    return false;
  };

  // initial bind
  $('#somelist li a').click(myAnchorHandler);

  // code where you input more li elements to the list with links
  $('#somelist').append(
    // bind your function to the element now, and then append it
    $('<li><a>hi</a></li>').find('a').click(myAnchorHandler).parent()
  );
});
person Alex Sexton    schedule 23.02.2010
comment
хорошее объяснение, хотя я не совсем понимаю терминологию. Любые идеи о различных решениях, возможно, в данный момент у меня нет идей. - person Richard; 23.02.2010
comment
Я могу рассказать об этом более подробно, если хотите, но более или менее, если вы хотите иметь возможность заблокировать что-то, что происходит на li, вам нужно либо использовать bind для обработки ваших кликов, либо вам нужно изменить что-то еще. обработчик в настоящее время находится на li, чтобы игнорировать все, что возникло в дочернем элементе привязки. - person Alex Sexton; 23.02.2010
comment
нет, вам не нужно вдаваться в подробности, я могу прочитать об этом. Сейчас меня больше интересует практическое решение. Я могу что-то сделать в событии li click, чтобы распознать, что я нажал на дочерний элемент. Я уже пробовал кое-что с e.target, но это даст только элемент li, верно? - person Richard; 23.02.2010
comment
Я добавил простой пример того, как использовать bind, даже если вы добавляете новые элементы в список. - person Alex Sexton; 23.02.2010
comment
Извините, сначала поместил комментарий не в тот раздел. Я не могу сейчас так быстро оценить, но спасибо, если это решение. Вы также говорите, что мне вообще не нужен прямой эфир в этой настройке. Я буду приятно удивлен, если это сработает, потому что контент со страницы добавляется динамически, и я всегда думал, что вам нужно жить, чтобы это работало. - person Richard; 24.02.2010
comment
Пока вы добавляете обработчики событий к своим элементам, их события будут обрабатываться. В случае с динамическим контентом вам просто нужно подождать, пока вы не разместите его там, чтобы заставить его работать. Другим решением может быть наличие скрытого элемента со всеми прикрепленными к нему событиями и запуск на нем clone(true) для возврата нового экземпляра с обработчиками событий. Это если вы не хотите писать html в своем коде или что-то в этом роде. - person Alex Sexton; 24.02.2010
comment
Нисколько. Ваше решение работает. Вы были абсолютно правы в использовании «bind». Я не знал этого о «живом». Спасибо. - person user113716; 24.02.2010
comment
Я только что проголосовал за вас, так как сейчас вы выглядите немного взволнованной. Не хотел тебя расстраивать. Основная концепция, которую вы сообщаете в своем ответе, точна. - person user113716; 24.02.2010
comment
Спасибо, что нашли ошибку, она исправлена. - person Alex Sexton; 24.02.2010

Решение от автора:

Я добавил все теги a, как указано выше, чтобы больше не путать с живым.

$(markers).each(function(i,marker){
    listitem = $("<li />") 
    .html("Location ") 
    .click(function(e){
        showLocation(marker, i);
    })
    .appendTo("#somelist");
    $("<a />")
    .html("<strong>"+ids[i]+"</strong>")
    .addClass('ol id')
    .click(function(){
        $('#ginfo').show();
        return false;
    })
    .appendTo(listitem);

Вот интересная страница, объясняющая всплытие событий: Как остановить всплытие событий с помощью jquery работает?

person Eric Leschinski    schedule 20.08.2013

Пусть обработчик тегов <a> возвращает false.

person Pointy    schedule 23.02.2010