jQuery $ (“. class”). click (); - кілька елементів, клацніть подію один раз


82

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

Сценарій полягає в тому, що я використовую 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});

Будь ласка, опублікуйте свій код, те, що ви говорите, для мене не має сенсу.
Лазар,

Так, опублікуйте код свого javascript, будь ласка.
Yngve B-Nilsen

1
Він повинен запускатися лише один раз, або це проблема з вашим HTML - можливо, один клас addproduct вкладений в інший, або в обробнику є помилка, яка запускає ajax двічі за один клік, в будь-якому випадку нам потрібно, щоб побачити докладніше код, щоб бути впевненим.
Саймон

3
жахливі запитання та відповіді. я стикаюся з подібною проблемою, але ні, де в початковому плакаті згадується рішення або метод до божевілля ... настільки знеохочує, що люди не можуть правильно використовувати цей сайт, але сподіваються бути розробником на будь-якому рівні.
ocergynohtna

Використовуйте data-id = "151", а потім $ (this) .data ('id')
Андрес СК

Відповіді:


120

Вибачення за натикання на цю стару нитку. У мене була та сама проблема зараз, і я хотів поділитися своїм рішенням.

$(".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

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

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 like

<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 запускається подія ones, ви просто перевіряєте кількість випадків класів у файлі та використовуєте для циклу для наступної логіки. для ідентифікації кількості випадків будь-якого класу, тегу або будь-якого елемента 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). Але коли я натискаю одне і те ж посилання вдруге і натискаю кнопку OK на модальному рівні, подія спрацьовує на кожному об’єкті, на .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-класу отримає кілька клікових подій. Наприклад, у моїх даних є 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.