2010-07-27 8 views
2

У меня есть список в списках. Когда пользователь нажимает на элемент списка (<li>), я хочу, чтобы появилось вложенное <ul>. Прежде чем я начал добавлять вложенные списки, я просто получил его, когда нажатие элемента списка запускало функцию. Теперь нажатие на любой из вложенных списков также выполняет эту функцию. Это имеет смысл, поскольку они являются частью элемента списка.jQuery нажмите на li с вложенной ul

Помимо упаковки <span> вокруг первой части элемента списка и запуска функции на этом, есть ли селектор, который позволит мне что-то запустить на родительском <li>, но не на его дочерние элементы, а не на дочерние списки и список элементов?

HTML:

<ul class="buckets">   
    <li class="bucket"> 
     <img src="arrow_group_collapsed_true.png" class="arrow"> 
     <img src="blue_folder.png" class="folder"> 
     View all 
    </li> 

    <li class="bucket"> 
     <img src="arrow_group_collapsed_false.png" class="arrow"> 
     <img src="blue_folder.png" class="folder"> 
     Groups 
     <ul style="display: block;"> 
      <li id="group_id_15036" class="group_bucket"> 
       <img src="arrow_group_collapsed_true.png" class="arrow"> 
       <img src="blue_folder.png" class="folder"> 
       Group 1 
      </li> 
      <li id="group_id_14910" class="group_bucket"> 
       <img src="arrow_group_collapsed_true.png" class="arrow"> 
       <img src="blue_folder.png" class="folder"> 
       Group 2 
      </li> 
     </ul> 
    </li> 
</ul> 

Javascript (не много, я могу показать больше, если необходимо):

$('li.bucket').live('click', 
    function() 
    { 
     // do stuff 
    }) 

Я хочу, нажмите на "группы" или "Все", чтобы запустить функция щелчка, но щелчок на «Группе 1» ​​или «Группе 2» не должен.

ответ

11

Там есть официальный способ, но в вашем случае, это может быть довольно дорогим:

$('li.bucket *').live('click', function(event) { event.stopPropagation() }); 

li «s Теперь дети будут иметь обработчик, который останавливает событие от распространяющихся вверх и вызывая li» ю.ш. обработчик. Попробуйте и посмотрите, не слишком ли замедлено приложение.

+0

Так что, если пользователь нажимает на что-нибудь вроде 'li.bucket li', что здесь будет? – hookedonwinter

+0

Ничего. Разве это не намеренное поведение? – MvanGeest

+0

Я просто хотел убедиться. Могу ли я затем переопределить это? Я хочу, чтобы все происходило, когда я щелкаю по более глубоким ссылкам, я просто не хочу, чтобы функция срабатывала и на верхнем. Если это имеет смысл. – hookedonwinter

2

вы можете контролировать функции выше OnMouseOver список элемента & удалить его onmouseout событие пункта. Но я не знаю, насколько эффективно это было бы против других способов.

+0

Прохладный идея. MvanGeest работал, но хорошо думал :) – hookedonwinter

+0

Хе-хе на самом деле эти идеи приходят, когда я слишком ленив, чтобы написать код jQuery ... довольно легко помочь людям, просто давая им идею, а не код: p – loxxy

1

Мне нравится решение @ MvanGeest, но есть лучший способ понять распространение события. Когда элемент кликается, содержащиеся элементы сначала получают событие и просачиваются через дерево. Если я понимаю ваш запрос, вы хотели бы запретить содержащиеся в нем ul отправлять события вверх по дереву. Я думаю, что здесь лучше визуально.

<ul> 
    <li></li> 
    <li onclick="ShowChildUL()"> 
    <ul onclick="function(event) { event.stopPropagation() }"> 
     <li onclick="DoSomethingFun()"></li> 
     <li></li> 
     </ul> 
    </li> 
</ul> 

В этом случае вы увидите, что OnClick на ул в середине остановит распространение до ли. Также event.stopPropagation() не является перекрестным браузером. Я рекомендую этот метод как функцию onclick.

function StopPropagation(e) { 
    var event = e || window.event; 

    [body of event handler function goes here] 

    if (event.stopPropagation) { 
    event.stopPropagation(); 
    } else { 
    event.cancelBubble = true; 
    } 
}