jQuery при нажатии возвращает неверный элемент при использовании $(this)

avatar
Mahsa
9 августа 2021 в 05:27
125
4
0

У меня есть список элементов одного класса. Я хочу получить точный элемент, когда я нажимаю на него. Когда я нажимаю first element, я получаю правильный ответ, а когда я нажимаю на вложенный элемент (например, first sub element), я получаю два результата: first sub element, а также first element. Чего я не понимаю, так это того, что когда я нажимаю на элемент, разве я не должен получать только тот элемент, для которого было вызвано это событие? Я хочу получить только first sub element, когда я нажимаю на этот li. Как я могу получить этот результат?

$(document).on('click', "li.category", function(){
  alert($(this).text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <ul>
    <li class="category">first element
      <ul>
        <li class="category">first sub element</li>
        <li class="category">second sub element</li>
      </ul>
    </li>
    <li class="category">second element</li>
  </ul>
</div>
Источник

Ответы (4)

avatar
Alireza Ahmadi
9 августа 2021 в 06:09
3

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

Другими словами, когда вы нажимаете на first sub element, вы также нажимаете на родителя элемента (я имею в виду first element), потому что ваша цель li.category, и они оба являются вашей целью.

Быстрое исправление использует event.stopPropagation(), чтобы остановить распространение события щелчка от самого внутреннего к родительскому, например:

$(document).on('click', "li.category", function(e){
  alert($(this).text());
  e.stopPropagation()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <ul>
    <li class="category">first element
      <ul>
        <li class="category">first sub element</li>
        <li class="category">second sub element</li>
      </ul>
    </li>
    <li class="category">second element</li>
  </ul>
</div>
avatar
Rhea
9 августа 2021 в 07:42
0

text() в родительском элементе возвращает текст всех его дочерних элементов. Таким образом, нажатие на first element приведет к выводу

First element
First Sub element
Second sub element

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

В противном случае, обратитесь здесь, чтобы получить текст только для это li

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

$(document).on('click', "li.category", function(e){
  var el = e.target
  if( this == el)
     alert($(el).text())
})
avatar
Nishant Singh
9 августа 2021 в 06:39
-1

Есть самый простой способ сделать это. Вы можете просто улучшить структуру кода, например, изменить <li class="category">first element на <li class="category"><span class="label">first element</span> и теперь в javascript вы измените запрос на:

  1. alert($(this).find('.label').text());
  2. Или $(document).on('click', "li.category .label", function(){

Дайте мне знать, если у вас есть другие мысли.

avatar
sikurro
9 августа 2021 в 05:51
0

Может быть что-то вроде этого

$('.category').on('click', function(){  
  let text = $(this)[0].childNodes[0].nodeValue.trim()
  alert(text);
  return false;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <ul>
    <li class="category">first element
      <ul>
        <li class="category">first sub element</li>
        <li class="category">second sub element</li>
      </ul>
    </li>
    <li class="category">second element</li>
  </ul>
</div>