jQuery $ (“. class”). click (); - nhiều yếu tố, nhấp vào sự kiện một lần


82

Tôi có nhiều lớp học trên một trang cùng tên. Sau đó, tôi có một sự kiện .click () trong JS của mình. Điều tôi muốn xảy ra là sự kiện nhấp chuột chỉ xảy ra một lần, bất kể có nhiều lớp trên trang của tôi.

Tình huống là tôi đang sử dụng AJAX để thêm vào giỏ hàng. Đôi khi trên trang chủ có thể có một sản phẩm nổi bật và một ưu đãi hàng đầu, có nghĩa là cùng một loại .add. # Productiontid # ở đó và khi nhấp vào thêm vào giỏ hàng, AJAX được kích hoạt hai lần.

Tôi đã nghĩ đến việc tạo 'khu vực nhấp chuột' để tôi sẽ có .container-name .add. # Pid # do đó tạo ra các nhấp chuột duy nhất.

Đây có phải là giải pháp duy nhất?

<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});

Vui lòng đăng mã của bạn, những gì bạn đang nói không có ý nghĩa đối với tôi.
Lazarus

Có, vui lòng đăng mã cho javascript của bạn.
Yngve B-Nilsen

1
Nó chỉ nên kích hoạt một lần, đó là vấn đề với HTML của bạn - có thể một lớp sản phẩm bổ sung được lồng trong một lớp khác hoặc có lỗi trong trình xử lý kích hoạt ajax hai lần cho một lần nhấp, theo cách chúng tôi cần xem đầy đủ hơn mã để chắc chắn.
Simon

3
hỏi và trả lời kinh khủng. Tôi đang gặp phải vấn đề tương tự nhưng không có nơi nào người đăng ban đầu đề cập đến một giải pháp hoặc phương pháp điên rồ ... đến nỗi mọi người không thể sử dụng trang web này đúng cách nhưng mong đợi trở thành nhà phát triển ở mọi cấp độ.
ocergynohtna

Sử dụng data-id = "151" rồi đến $ (this) .data ('id')
Andres SK

Câu trả lời:


120

Xin lỗi vì đã làm hỏng chủ đề cũ này. Tôi gặp vấn đề tương tự ngay bây giờ và tôi muốn chia sẻ giải pháp của mình.

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

event.StopPropagationevent.StopImmediatePropagation()nên thực hiện thủ thuật.

Việc có bộ chọn .class cho trình xử lý Sự kiện sẽ dẫn đến bubblingsự kiện nhấp chuột (đôi khi đối với phần tử Gốc, đôi khi đối với phần tử Con trong DOM).

event.StopPropagation()phương thức đảm bảo rằng sự kiện không bong bóng đối với các phần tử Cha, trong khi event.StopImmediatePropagation()phương thức đảm bảo rằng sự kiện không bong bóng đối với các phần tử Con của bộ chọn lớp mong muốn.

Nguồn: https://api.jquery.com/event.stoppropagation/ https://api.jquery.com/event.stopim ngaypropagation/


1
Đây là giải pháp đúng đắn. Nếu bạn gọi bấm vào một lớp với jQuery, nó có thể bong bóng tới các phần tử khác và đăng ký nhiều lần bấm. Dừng sự lan truyền của sự kiện nhấp chuột đó đến các phần tử khác là cách giải quyết vấn đề này. Tôi nghĩ một số câu trả lời khác đã hiểu sai những gì rất có thể xảy ra ở đây.
RATKNUKKL

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

nó hoạt động Chưa bao giờ thấy trên chức năng được sử dụng như thế này
Nabeel Khan

Làm thế nào tôi nên gọi câu trả lời đã cho từ một sự kiện khác ??
Murad Hasan

1
Đã thử mọi thứ, đây là giải pháp duy nhất có hiệu quả.
Matt

Giải thích về tham số thứ hai: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

Chúng tôi có thể thấy trình xử lý nhấp chuột của bạn không? Bạn đang gắn 5 người nghe vào 5 yếu tố khác nhau. Tuy nhiên, khi người dùng nhấp vào phần tử, chỉ một sự kiện được kích hoạt.

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

  addToCart(productId);
});

Nếu giải pháp này không hiệu quả, tôi muốn xem xét trình xử lý nhấp chuột của bạn.


29

khi bạn nhấp vào div với lớp addproduct, một sự kiện được kích hoạt cho phần tử cụ thể đó, không phải năm. bạn đang làm sai điều gì đó trong mã của bạn nếu sự kiện được kích hoạt 5 lần.


24
Tôi thích cách câu trả lời này nói rõ ràng và sau đó querent nói rằng họ sẽ kiểm tra mã của họ như thể đó không phải là điều họ sẽ làm ngay từ đầu: D.
KI4JGT

1
Tôi ngạc nhiên vì đây là câu trả lời được chấp nhận. Như đã đề cập bởi Ivan Kalafatić, vấn đề là sự kiện nhấp chuột đang được truyền sang các phần tử khác. Giải pháp là dừng sự lan truyền này. Vui lòng xem câu trả lời của Ivan Kalafatić để biết cách thực hiện điều đó. chỉnh sửa: chỉ cần nhận thấy câu trả lời đúng thực sự được viết bởi Ivan Kalafatić chứ không phải Machavity (người đã chỉnh sửa nó). Đã sửa lỗi của tôi.
RATKNUKKL

14

Trong tình huống này, tôi sẽ thử:

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

    //your code here

 });

sau đó, nếu bạn cần thực hiện một cái gì đó trong các phần tử khác có cùng lớp, hãy nhấp vào một cái hoặc bạn có thể lặp qua các phần tử:

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

      //your code here
     }
  );
 }
);

11

Tôi nghĩ rằng bạn thêm sự kiện nhấp chuột năm lần. Hãy thử đếm xem bạn làm điều này bao nhiêu lần.

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

Sử dụng AngularJS, tôi nhận thấy nó đã sao chép thẻ script để kiểm tra x số lần! Cảm ơn vì các giải pháp khả thi.
Dean Meehan

8

Điều này sẽ khắc phục và trở thành một thói quen tốt: .unbind ()

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

Xin lưu ý rằng tính năng hủy liên kết đã không còn được dùng nữa (từ api.jquery.com/unbind ): Kể từ jQuery 3.0, .unbind () đã không được dùng nữa. Nó đã được thay thế bởi phương thức .off () kể từ jQuery 1.7, vì vậy việc sử dụng nó đã không được khuyến khích.
Tomer

6

Tôi đã giải quyết nó bằng cách sử dụng lệnh gọi hàm jquery nội tuyến như

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

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

Bạn tiết kiệm ngày của tôi Dude!
Smaïne

5

tôi chỉ có cùng một vấn đề. Trong trường hợp của tôi, mã PHP được tạo vài lần cùng một mã jQuery và đó là trình kích hoạt nhiều lần.

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

(PHP MULTIPLE GENERATER CONSERS được tạo cùng một mã nhiều lần)

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

Giải pháp của tôi là tách tập lệnh trong một tệp php khác và tải tệp đó MỘT LẦN.


Nhận xét của bạn đã dẫn tôi đến giải pháp của mình - Tôi gặp vấn đề tương tự, một cú nhấp chuột đã kích hoạt sự kiện cho mọi phần tử. Đó là vì tôi đã mắc kẹt tập lệnh trong chế độ xem một phần (asp mvc) được tải nhiều lần. Cảm ơn bạn.
Hanshan

2

Chỉ cần nhập mã vào đây Trong JQuery, một sự kiện được kích hoạt, bạn chỉ cần kiểm tra số lần xuất hiện của các lớp trong tệp và sử dụng vòng lặp for cho logic tiếp theo. để xác định số lần xuất hiện của bất kỳ lớp, thẻ hoặc bất kỳ phần tử DOM nào thông qua JQuery: var len = $ (". addproduct"). length;

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

1

Tôi đã từng gặp vấn đề tương tự. Nguyên nhân là tôi đã có cùng một jquery nhiều lần. Anh ta đã bị đặt trong một vòng lặp.

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

Vì lý do này đã được kích hoạt nhiều lần


1

Tôi đã tự mình thử nó trong dự án của mình.

Tất cả các hàng của tôi trong một bảng đều có "địa chỉ liên hệ" của lớp:

Tất cả các hàng của tôi trong một bảng có một "liên hệ" của lớp.

Mã của tôi trông như thế này:

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);
});

Và lần đầu tiên tôi sợ hãi khi thấy toàn bộ các hàng của mình là kết quả trong bảng điều khiển Firebug khi tôi thực thi mã:

Ảnh chụp màn hình bảng điều khiển Firebug sau khi thực thi mã

Nhưng sau đó tôi nhận ra rằng sự kiện nhấp chuột không được kích hoạt, vì không có hộp thoại cảnh báo nào xuất hiện. Firebug chỉ cho bạn thấy các phần tử bị ảnh hưởng bởi việc xác định quá mức nhấp chuột. Vì vậy, không có gì phải lo lắng.


1

Hãy thử sử dụng .off()trình xử lý:

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

Tôi đính kèm một trình xử lý sự kiện nhấp chuột trên nút phương thức OK để hoạt động trên clicksự kiện của đối tượng với lớp .archive-link.

Trong lần nhấp đầu tiên, sự kiện chỉ kích hoạt trên .archive-linkđối tượng mà tôi đã yêu cầu hàm hoạt động trên ( var linkObj). Nhưng khi tôi nhấp vào cùng một liên kết lần thứ hai và nhấn OK trên phương thức, sự kiện sẽ kích hoạt trên mọi đối tượng .archive-linkmà tôi đã nhấp trước đó.

Tôi đã sử dụng các giải pháp trên nhưng không may là không hoạt động. Đó là khi tôi gọi .off () trong hàm nhấp vào nút OK của phương thức thì quá trình truyền đã dừng lại. Tôi hi vọng cái này giúp được.


1

Câu hỏi này đã được giải quyết và cũng nhận được rất nhiều phản hồi, nhưng tôi muốn thêm điều gì đó vào nó. Tôi đang cố gắng tìm hiểu, tại sao lần nhấp của tôi lại khiến anh ấy bắn 77 lần mà không phải một lần.

trong mã của tôi, tôi có một từng, chạy một phản hồi json và hiển thị nó dưới dạng div với các nút. Và sau đó tôi đã khai báo sự kiện nhấp chuột bên trong mỗi.

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

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

Nếu bạn viết mã của mình như thế này, nút .test của lớp sẽ nhận được nhiều sự kiện nhấp chuột. Ví dụ: dữ liệu của tôi có 77 dòng, vì vậy mỗi dòng sẽ chạy 77 lần, có nghĩa là tôi sẽ từ chối sự kiện nhấp chuột trên lớp 77 lần. Khi bạn nhấp vào phần tử, nó sẽ được bắn 77 lần.

Nhưng nếu bạn làm hỏng nó như thế này:

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

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

bạn đang khai báo phần tử nhấp chuột sau mỗi phần tử. Điều đó có nghĩa là mỗi phần tử sẽ chạy 77 lần và phần tử nhấp chuột sẽ chỉ được khai báo một lần. Vì vậy, nếu bạn nhấp vào phần tử, nó sẽ chỉ được kích hoạt một lần.


1

Chỉ cần làm dưới đây mã là nó hoạt động hoàn toàn tốt

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


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

}

0

Xin chào, xin lỗi vì đã đăng bài này chỉ cần đối mặt với vấn đề này và tôi muốn đưa ra trường hợp của mình.

Mã của tôi trông như thế này.

<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>

Mã 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

sự kiện của bạn chỉ được kích hoạt một lần ... vì vậy mã này có thể hoạt động, hãy thử điều này

    $(".addproduct,.addproduct,.addproduct,.addproduct,.addproduct").click(function(){//do     something fired 5 times});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.