Невозможно назначить кнопку для разделения поведения с помощью: not () - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть приложение HTML5, в котором есть таблица (идентификатор - #myTable в оставшейся части этого вопроса). Таблица заполняется запросом ajax.

После ответа ajax одна строка таблицы выглядит следующим образом:

<tr>
    <td>ID 001</td>
    <td>Foo</td>
    <td>Bar</td>
    <td>Baz</td>
    <td><a href="/fge?id=001" class="btn-fge">Find group entries</a></td>
</tr>

Якорь в последнем столбце isn ' присутствует на каждом ряду. Появляется только для определенных строк. Если якорь не появляется, отображается пустая строка: <td></td>.

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

$('#myTable tbody').on('click', 'td', function (e) { 
    var tr = $(this).closest('tr');

    // Code to expand/collapse tr
    // ...

    // Ajax request for additional row data
    // ...
}

Все это работало без проблем.

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

Я прочитал Проверьте, не имеет ли выбранный элемент определенного c класса и попытался нацелиться .btn-fge с использованием условия :not() следующим образом.

$('#myTable tbody').on('click', 'td:not(.btn-fge)', function (e) {

}

Это не работает (хотя я полагаю, что это может быть потому, что .btn-fge не класс <td>, а скорее якорь внутри него?). Поведение сворачивающейся / расширяющейся строки все еще срабатывает, после чего браузер перенаправляет на значение href. В приведенном примере поведение выглядит следующим образом:

  1. Щелкните .btn-fge.
  2. Строка развернута (или, если она уже развернута, свернута).
  3. Браузер следует href на .btn-fge, поэтому в этом случае перенаправляет на /fge?id=001.

Я хочу, чтобы (1) следовал (3), но не (2) при нажатии .btn-fge.

Я попытался войти console.log($(this));, а затем e.preventDefault(). Неважно, где находится строка, по которой я щелкаю - независимо от того, находится она на кнопке или нет - она ​​выдает тот же результат, как показано ниже.

enter image description here

Как можно ли настроить таргетинг таким образом, чтобы поведение кнопки отличалось от нажатия других мест внутри строки?

Я использую jquery версию 3.2.1 и предпочел бы решение jquery, но ваниль JavaScript один также будет приемлемым.

Редактировать - я сделал скрипку здесь https://jsfiddle.net/adrq0nhz/, и если вы щелкнете где-нибудь внутри таблицы, появится консоль «Это все еще стреляет», что фактически является проблемой якоря не имея отдельного поведения. Примечание: класс .btn-fge находится на привязке, а не <td>, и это нельзя изменить.

Ответы [ 4 ]

2 голосов
/ 18 февраля 2020

Вы можете использовать свойство target объекта события, чтобы проверить, по какому элементу щелкнули.

$('#myTable tbody').on('click', 'td', function(e) {
  //used prevent default for demonstration purposes to avoid the href link being opened.
  e.preventDefault();
  if ($(e.target).is('a.btn-fge')) {
    console.log('clicked on anchor with the class btn-fge');
  } else {
    console.log('clicked outside of anchor with the class btn-fge');
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="myTable">
  <tbody>
    <tr>
      <td>ID 001</td>
      <td>Foo</td>
      <td>Bar</td>
      <td>Baz</td>
      <td><a href="/fge?id=001" class="btn-fge">Find group entries</a></td>
    </tr>
  </tbody>
</table>
1 голос
/ 18 февраля 2020

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

Обработчик события щелчка строки должен обрабатывать только события щелчка строки, а не n't обрабатывать какое-то другое событие.

Эта парадигма может очень быстро запутаться с дополнительными кнопками / входами / выборами - лучше вообще не лезть в обработчик.

Вы можете остановить строку, получив щелчок e.stopPropagation() - это позволяет вам все еще щелкать в той же ячейке вокруг кнопки, например:

$("table tr td").click(() => console.log("row click"));
$(".btn-fge").click((e) => e.stopPropagation());
table {
  border-collapse: collapse;
}

table, th, td {
  border: 1px solid black;
  padding:2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
    <td>ID 001</td>
    <td>Foo</td>
    <td>Bar</td>
    <td>Baz</td>
    <td><a href="#" class="btn-fge">Find group entries</a>click here also works</td>
</tr>
</table>

Обновленная скрипта: https://jsfiddle.net/8ahn6dc1/


Альтернативой является не добавлять щелчок к клетка кнопки. Замечено, что вы не хотите изменять HTML, но вы все равно можете «изменить» HTML через js, пример:

$(".btn-fge").closest("td").addClass("noclick");
$("table tr td:not(.noclick)").click(() => console.log("row click"));
table {
  border-collapse: collapse;
}

table, th, td {
  border: 1px solid black;
  padding:2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
    <td>ID 001</td>
    <td>Foo</td>
    <td>Bar</td>
    <td>Baz</td>
    <td><a href="#" class="btn-fge">Find group entries</a>click here does nothing</td>
</tr>
</table>
1 голос
/ 18 февраля 2020

Очень похоже на метод Марка, вы также можете использовать метод .matches и передать ему имя класса, на который хотите нацелиться.

$('#myTable tbody').on('click', function(e) {
  if (e.target.matches('[class=btn-fge]')) {
    console.log('anchor clicked');
  } else {
    console.log('<td> clicked');
  }
  e.preventDefault();
});
0 голосов
/ 18 февраля 2020

Вы можете использовать jQuery метод .find ()

$('#myTable tbody').on('click', 'td', function (e) {

    // proceed only if a child does not exist with class .btn-fge 
    if(!$(this).find('.btn-fge').length){

        // non-anchor td clicked
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...