jQuery $ («. класс»). click (); - несколько элементов, событие щелчка один раз


83

У меня несколько классов на одноименной странице. Затем у меня есть событие .click () в моем JS. Я хочу, чтобы событие щелчка происходило только один раз, независимо от нескольких классов на моей странице.

Сценарий таков, что я использую AJAX для добавления в корзину. Иногда на домашней странице может быть избранный продукт и главное предложение, что означает, что там один и тот же класс .add. # Productid #, и при нажатии кнопки добавления в корзину AJAX запускается дважды.

Я подумал о создании «областей щелчка», чтобы иметь .container-name .add. # Pid #, что дает уникальные щелчки.

Это единственное решение?

<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>


$(".addproduct").click(function(){//do something fired 5 times});

Пожалуйста, опубликуйте свой код, то, что вы говорите, для меня не имеет смысла.
Lazarus

Да, опубликуйте код для вашего javascript, пожалуйста.
Yngve B-Nilsen

1
Он должен запускаться только один раз, это либо проблема с вашим HTML - возможно, один класс addproduct вложен в другой, либо есть ошибка в обработчике, который запускает ajax дважды для одного щелчка, в любом случае нам нужно, чтобы увидеть более полный код, чтобы быть уверенным.
Саймон

3
ужасные вопросы и ответы. У меня аналогичная проблема, но нигде в первоначальном плакате не упоминается решение или метод безумия ... так обескураживает, что люди не могут использовать этот сайт должным образом, но рассчитывают стать разработчиком на любом уровне.
ocergynohtna

Используйте data-id = "151", а затем $ (this) .data ('id')
Андрес SK

Ответы:


121

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

$(".yourButtonClass").on('click', function(event){
    event.stopPropagation();
    event.stopImmediatePropagation();
    //(... rest of your JS code)
});

event.StopPropagationи event.StopImmediatePropagation()должен сделать свое дело.

Наличие селектора .class для обработчика событий приведет bubblingк событию щелчка (иногда для родительского элемента, иногда для дочерних элементов в DOM).

event.StopPropagation()Метод гарантирует, что событие не всплывает в родительские элементы, а event.StopImmediatePropagation()метод гарантирует, что событие не всплывает в дочерние элементы желаемого селектора класса.

Источники: https://api.jquery.com/event.stoppropagation/ https://api.jquery.com/event.stopimmediatepropagation/


1
Это правильное решение. Если вы вызываете щелчок по классу с помощью jQuery, он может переходить к другим элементам и регистрировать множественные щелчки. Как решить эту проблему, остановив распространение этого события щелчка на другие элементы. Я думаю, что некоторые другие ответы неправильно поняли, что, скорее всего, здесь происходило.
RATKNUKKL 06

90
$(document).on('click', '.addproduct', function () {
    // your function here
});

это работает? никогда не видел, чтобы функция использовалась таким образом
Набил Хан

Как мне вызвать данный ответ из другого события ??
Мурад Хасан

1
Все перепробовал, это единственное решение, которое сработало.
Мэтт

Пояснение ко второму параметру:A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element.
zwlxt

45

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

$(".addproduct").click(function(){
  // Holds the product ID of the clicked element
  var productId = $(this).attr('class').replace('addproduct ', '');

  addToCart(productId);
});

Если это решение не работает, я хотел бы посмотреть на ваш обработчик кликов.


29

когда вы нажимаете div с классом addproduct, для этого конкретного элемента запускается одно событие, а не пять. вы делаете что-то не так в своем коде, если событие запускается 5 раз.


24
Мне нравится, как в этом ответе утверждается очевидное, а затем кверент говорит, что они собираются проверить свой код, как если бы они изначально не собирались этого делать: D.
KI4JGT

1
Я удивлен, что это принятый ответ. Как упоминал Иван Калафатич, проблема в том, что событие щелчка распространяется на другие элементы. Решение состоит в том, чтобы остановить это распространение. См. Ответ Ивана Калафатича, чтобы узнать, как это сделать. редактировать: только что заметил, что правильный ответ на самом деле был написан Иваном Калафатичем, а не Мачавити (который его редактировал). Исправил мою ошибку.
RATKNUKKL 06

14

В этой ситуации я бы попробовал:

$(document).on('click','.addproduct', function(){

    //your code here

 });

затем, если вам нужно выполнить что-то в других элементах с тем же классом, щелкнув один из них, вы можете перебрать элементы:

$(document).on('click','.addproduct', function(){
   $('.addproduct').each( function(){

      //your code here
     }
  );
 }
);

11

Я думаю, вы добавляете событие щелчка пять раз. Попробуйте посчитать, сколько раз вы это делаете.

console.log('add click event')
$(".addproduct").click(function(){ });

Используя AngularJS, я заметил, что он скопировал тег скрипта для тестирования x количество раз! Спасибо за возможное решение.
Дин Михан

8

Это должно исправить это и должно стать хорошей привычкой: .unbind ()

$(".addproduct").unbind().click(function(){
   //do something 
});

Обратите внимание, что unbind устарел (с api.jquery.com/unbind ): начиная с jQuery 3.0, .unbind () устарел. Он был заменен методом .off () начиная с jQuery 1.7, поэтому его использование уже не поощрялось.
Томер

6

Я решил это, используя встроенный вызов функции jquery, например

<input type="text" name="testfield" onClick="return testFunction(this)" /> 

<script>
  function testFunction(current){
     // your code go here
  }
</script>

Ты спас мне день, чувак!
Smaïne

5

У меня была такая же проблема. В моем случае PHP-код несколько раз генерировал один и тот же код jQuery, и это был множественный триггер.

<a href="#popraw" class="report" rel="884(PHP MULTIPLE GENERATER NUMBERS)">Popraw / Zgłoś</a>

(НОМЕРА НЕСКОЛЬКИХ ГЕНЕРАТОРОВ PHP также генерировали один и тот же код несколько раз)

<script type="text/javascript">
$('.report').click(function(){...});
</script>

Мое решение заключалось в том, чтобы отделить скрипт в другом файле php и загрузить этот файл ОДИН РАЗ.


Ваш комментарий привел меня к моему решению - у меня была такая же проблема, один щелчок запускал событие для каждого элемента. Это произошло потому, что я застрял скрипт в частичном представлении (asp mvc), которое загружалось много раз. Спасибо.
Hanshan

2

Просто введите код здесь. В JQuery, когда запускается одно событие, вы просто проверяете количество вхождений классов в файл и используете цикл for для следующей логики. для определения количества вхождений любого класса, тега или любого элемента DOM через JQuery: var len = $ (". addproduct"). length;

 $(".addproduct").click(function(){
       var len = $(".addproduct").length; 
       for(var i=0;i<len;i++){
          ...
        }
 });

1

У меня такая же проблема. Причина в том, что у меня был один и тот же jquery несколько раз. Его поместили в петлю.

$ (". AddProduct"). click (function () {});
$ (". AddProduct"). click (function () {});
$ (". AddProduct"). click (function () {});
$ (". AddProduct"). click (function () {});
$ (". AddProduct"). click (function () {});

По этой причине стрелял несколько раз


1

Сам пробовал в своем проекте.

Все мои строки в таблице имеют класс «контакт»:

Все мои строки в таблице имеют класс «контакт».

Мой код выглядит так:

var contactManager = {};

contactManager.showEditTools = function(row) {
  console.debug(row);
}

$('.contact').click(function(event){
  console.log("this should appear just once!");
  alert("I hope this will appear just once!");
  contactManager.showEditTools(event);
});

И я сначала испугался увидеть свои целые строки в результате в консоли Firebug, когда выполнил код:

Скриншот консоли Firebug после выполнения кода

Но потом я понял, что событие щелчка не было запущено, потому что не появилось диалоговое окно с предупреждением. Firebug показывает вам только те элементы, на которые влияет перекрытие щелчка. Так что волноваться не о чем.


1

Попробуйте воспользоваться .off()обработчиком:

$(function () {
    $(".archive-link").click(function (e) {
        var linkObj = $(this);
        var cb = $("#confirm-modal");
        cb.find(".modal-body").append("<p>Warning message.</p>");
        cb.modal('show'); 
        cb.find(".confirm-yes").click(function () {
            $(this).off(); //detach this event
            //ajax call yada yada..
        }

Я прикрепляю обработчик события щелчка к модальной кнопке OK, чтобы действовать при clickсобытии объекта с классом .archive-link.

При первом нажатии событие срабатывает только для того .archive-linkобъекта, на который я просил функцию действовать ( var linkObj). Но когда я нажимаю ту же ссылку во второй раз и нажимаю ОК в модальном окне, событие срабатывает для каждого объекта, .archive-linkкоторый я щелкнул ранее.

Я использовал приведенные выше решения, но, к сожалению, не сработал. Когда я вызвал .off () в модальной функции щелчка кнопки OK, распространение остановилось. Надеюсь, это поможет.


1

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

в моем коде у меня был каждый, запускающий ответ json и отображающий его как div с кнопками. Затем я объявил событие щелчка внутри каждого файла.

$(data).each(function(){
    button = $('<button>');
    button.addClass('test-button');
    button.appendTo("body");

    $('.test-button').click(function(){
        console.log('i was clicked');
    })
})

Если вы напишете свой код таким образом, класс .test-button получит несколько событий нажатия. Например, в моих данных 77 строк, поэтому каждая будет выполняться 77 раз, это означает, что я отклоню событие щелчка в классе 77 раз. Когда вы нажимаете на элемент, он срабатывает 77 раз.

Но если вы запишете это так:

$(data).each(function(){
    button = $('<button>');
    button.addClass('test-button');
    button.appendTo("body");
})

    $('.test-button').click(function(){
        console.log('i was clicked');
    })

вы объявляете элемент щелчка после каждого. Это означает, что каждый из них будет выполнен 77 раз, а элемент щелчка будет объявлен только один раз. Итак, если вы щелкните элемент, он будет активирован только один раз.


1

Просто сделайте код ниже, он работает абсолютно нормально

$(".addproduct").on('click', function(event){
    event.stopPropagation();
    event.stopImmediatePropagation();
    getRecord();
});


function getRecord(){
   $(".addproduct").each(function () {
       console.log("test");
       });

}

0

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

Мой код выглядит так.

<button onClick="product.delete('1')" class="btn btn-danger">Delete</button>
<button onClick="product.delete('2')" class="btn btn-danger">Delete</button>
<button onClick="product.delete('3')" class="btn btn-danger">Delete</button>
<button onClick="product.delete('4')" class="btn btn-danger">Delete</button>

Код Javascript

<script>
 var product = {
     //  Define your function
     'add':(product_id)=>{
          //  Do some thing here
     },

     'delete':(product_id)=>{
         //  Do some thig here
     }
 }
</script>

0

$(document).ready(function(){

    $(".addproduct").each(function(){
          $(this).unbind().click(function(){
               console.log('div is clicked, my content => ' + $(this).html());
           });
     });
}); 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="addproduct 151">product info 1</div>
<div class="addproduct 151">product info 2</div>
<div class="addproduct 151">product info 3</div>
<div class="addproduct 151">product info 4</div>
<div class="addproduct 151">product info 5</div>


-5

ваше событие запускается только один раз ... поэтому этот код может работать, попробуйте это

    $(".addproduct,.addproduct,.addproduct,.addproduct,.addproduct").click(function(){//do     something fired 5 times});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.