Событие клика срабатывает дважды, но устанавливается только один раз - PullRequest
1 голос
/ 23 октября 2019

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

JS Fiddle щелкните по одному из имен, чтобы кнопка переключения былаТриггер, это не произойдет, если вы щелкнете за пределами элемента метки, тогда он будет активирован только один раз.

Я прикрепляю событие ко всем элементам с классом 'testit', когда я регистрирую элементыЯ получаю список узлов длиной 1, когда я регистрирую, сколько раз цикл foreach работает, он запускается один раз.

enter image description here

Если я удаляюв Javascript никакие события не прикреплены.

    // SELECTER DEN FEATURED JOKE
    $sql = " SELECT t1.cat_id,
            t1.cat_name,
            t1.cat_parent,
            t1.cat_type
            FROM categories t1
            ORDER BY t1.cat_parent,
            t1.cat_name";
    $stmt = $dbCon->prepare($sql);
    $stmt->execute();
    $count = $stmt->rowCount();
    if ($count > 0) {
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $orders = [];
        foreach($rows as $row){
            $cat_parent = $row['cat_parent'];
            if($cat_parent == 0){
                $orders[$row['cat_id']]['parent'] = [
                    'cat_id' => $row['cat_id'],
                    'cat_name' => $row['cat_name'],
                    'cat_parent' => $row['cat_parent'],
                    'cat_type' => $row['cat_type']
                ];
                continue;
            }

            if ($cat_parent != 0) {
                $orders[$cat_parent][] = [
                    'cat_id' => $row['cat_id'],
                    'cat_name' => $row['cat_name'],
                    'cat_parent' => $row['cat_parent'],
                    'cat_type' => $row['cat_type']
                ];
                continue;
            }
        }

        $filter_html  = '<form id="filter__form" class="filter__form testit">';
        $filter_html .= '<ul class="filter__ul main">';
        foreach($orders as $order){
            $cat_id     = escape($order['parent']['cat_id']);
            $para       = escape($order['parent']['cat_id']);
            $cat_name   = escape($order['parent']['cat_name']);
            $cat_parent = escape($order['parent']['cat_parent']);
            $cat_type   = escape($order['parent']['cat_type']);

            $filter_html .= '<label class="filter__label parent" for="filter_'.$cat_id.'">';
            $filter_html .= '<p class="noselect">'.$cat_name.'</p>';
            $filter_html .= '<input id="filter_'.$cat_id.'" type="checkbox" value="'.$cat_id.'" name="cat['.$cat_id.']" class="cat_parent" data-show="cat_subs_'.$cat_id.'">';
            $filter_html .= '<i></i>';
            $filter_html .= '</label>';
        }
        $filter_html .= '<input type="hidden" name="CSRFToken" value="'.$_SESSION['CSRFToken'].'">';
        $filter_html .= '</ul>';
        $filter_html .= '</form>';
    }
?>

<div class="filter__head">
    <h3 class="">
        Filter - Dashboard
    </h3>
</div>

<?php
    echo $filter_html;
?>

Javascript

    window.addEventListener("load", function (e) {


        var testit = document.querySelectorAll('.testit');

        console.log(testit);

        testit.forEach(function(e){
            console.log('TESTIT');
            e.addEventListener('click', function(){
                alert('Hello world');
            });
        });
   });

Таким образом, событие запускается дважды, что подтверждается в консоли, или путем создания оповещения при его запуске,длина объекта узла равна 1, что также подтверждается, если я его утешаю, если я удаляю Javascript, никакие события не прикрепляются, так что происходит?

Если я делаю кнопку в нижней части echo $filter_html с классом testit, аи я щелкаю тот, который будет срабатывать только один раз, в чем разница, как он может срабатывать дважды в одном конкретном элементе и один раз в другом, то же событие?.

Если я присоединяю событие mouseup, все срабатывает только один раз.

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

CSS

.filter__head h3{
    padding: 15px;
    background-color: #eee;
    text-align: start;
    color: #4a4a4a;
}
.filter__form{
    max-height: 70vh;
    height: 600px;
    overflow: auto;
}
.filter__form .filter__ul .filter__label{
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    border-bottom: 1px solid rgba(0,0,0,0.06);
    padding: 15px 20px;
    cursor: pointer;
}
.filter__form .filter__ul .filter__label:last-child {
  border-bottom: 1px solid #BBB;
}
.filter__form .filter__ul .filter__label > input {
  display: none;
}
.filter__form .filter__ul .filter__label i {
  display: inline-block;
  float: right;
  padding: 2px;
  width: 40px;
  height: 20px;
  border-radius: 13px;
  vertical-align: middle;
  transition: .25s .09s;
  position: relative;
  background: #d8d9db;
  box-sizing: initial;
}
.filter__form .filter__ul .filter__label i:after {
  content: " ";
  display: block;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  position: absolute;
  left: 2px;
  transition: .25s;
}
.filter__form .filter__ul .filter__label > input:checked + i {
  background: #4bd865;
}
.filter__form .filter__ul .filter__label > input:checked + i:after {
  -webkit-transform: translateX(20px);
          transform: translateX(20px);
}
.filter__form .filter__ul .filter__label:hover {
  cursor: pointer;
}

Ответы [ 2 ]

1 голос
/ 23 октября 2019

Второе событие клика в форме вызывается нажатием на элемент label, обертывающий вход и другие элементы. Элемент метки инициирует событие щелчка на связанном элементе ввода. MDN говорит :

" Когда label нажимается или касается и связывается с элементом управления формы, результирующее событие нажатия также вызывается для связанногоcontrol."

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

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

0 голосов
/ 23 октября 2019

Что происходит, так это то, что вы присоединяете событие к самой форме, это единственный элемент с классом testit.

Попробуйте вместо этого добавить прослушиватель события к входам и использовать объект события для идентификации каждого входа:

var inputs = document.querySelectorAll('.cat_parent'); 
  inputs.forEach(function(input) { 
     input.addEventListener('click', function(event) { // you need to pass the event
       alert(event.currentTarget.id); // Now in the event object you have just the one that was clicked
      });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...