Làm cách nào để thêm trình nghe sự kiện riêng lẻ bằng cách sử dụng jquery .each ()?

Jan 08 2021

Tôi có một thiết lập đơn giản: Hai nút với các giá trị khác nhau. Tôi muốn sử dụng hàm .each () từ jquery để thêm trình xử lý sự kiện nhấp chuột vào mỗi nút chỉ ghi lại các giá trị của mỗi nút. Nhưng bằng cách nào đó khi sử dụng .each (), jquery sẽ ghi đè trình xử lý nhấp chuột cho (các) nút trước đó. Điều này khiến tôi có hai câu hỏi:

  1. Tại sao vậy?
  2. Làm cách nào để thêm trình nghe sự kiện riêng lẻ vào tập hợp các đối tượng jquery?

Xem mã bên dưới

  <html lang="en">
    
    <head>
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        <script>
            $(() => { $(`button[toggle]`).each((_, button) => {
                    let $toggle = $(button);
                    type = $toggle.attr("type"); value = $toggle.attr("value");
                    $toggle.on("click", () => {
                        console.log(type, value);
                    });
                });
            });
        </script>
    
    </head>
    
    <body>
        <div>
            <button toggle type="one" value="true">One</button>
            <button toggle type="two" value="false">Two</button>
        </div>
    </body>
    
    </html>

Trả lời

1 RoryMcCrossan Jan 08 2021 at 20:14

Vấn đề trong mã của bạn là do bạn đã khai báo ngầm các biến typevalue, vì vậy chúng nằm trong windowphạm vi. Như vậy, mỗi lần lặp sau sẽ ghi đè các giá trị để chỉ các giá trị cuối cùng được nhìn thấy sau khi vòng lặp kết thúc.

Để khắc phục điều này, hãy xác định các biến trong vòng lặp:

$(() => { $(`button[toggle]`).each((_, button) => {
    let $toggle = $(button);
    let type = $toggle.attr("type"); let value = $toggle.attr("value");
    $toggle.on("click", () => {
      console.log(type, value);
    });
  });
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<div>
  <button toggle type="one" value="true">One</button>
  <button toggle type="two" value="false">Two</button>
</div>

Tuy nhiên , bạn không cầneach()vòng lặp. Bạn có thể khắc phục sự cố và cải thiện chất lượng mã bằng cách liên kết cùng một trình xử lý sự kiện với tất cả cácbuttonphần tử và sử dụng thuộctargettính của sự kiện được nâng lên để truy cập các thuộc tính của chúng.

Ngoài ra, hãy lưu ý rằng việc thêm các thuộc tính không chuẩn của riêng bạn, toggletrong trường hợp này, có thể dẫn đến các vấn đề trong giao diện người dùng và JS. Một cách tiếp cận tốt hơn là sử dụng một lớp để nhóm các phần tử.

Cuối cùng, onetwokhông phải là giá trị hợp lệ cho typethuộc tính. dataThay vào đó, hãy sử dụng một thuộc tính để đính kèm siêu dữ liệu tùy chỉnh của riêng bạn vào một phần tử.

Với tất cả những gì đã nói, hãy thử điều này:

jQuery($ => {
  $('.toggle').on('click', e => { let $toggle = $(e.target); let type = $toggle.data("type"); 
    let value = $toggle.prop("value");
    console.log(type, value);
  });
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<div>
  <button class="toggle" data-type="one" value="true">One</button>
  <button class="toggle" data-type="two" value="false">Two</button>
</div>

1 prasanth Jan 08 2021 at 20:10

sử dụng $(this)bên trong lệnh gọi lại nhấp chuột

$(() => {
  $(`button[toggle]`).each((_, button) => { $(button).on("click", function(){
       type   = $(this).attr("type"); value = $(this).attr("value");
      console.log(type, value);
    });
  });
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<button toggle type="one" value="true">One</button>
<button toggle type="two" value="false">Two</button>

Và cũng không cần phải đề cập đến bên trong mỗi cuộc gọi lại. Bạn có thể gọi theo cách bình thường như bên dưới

$(() => { $(`button[toggle]`).on("click", function(){
       type   = $(this).attr("type"); value = $(this).attr("value");
      console.log(type, value);
    });
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<button toggle type="one" value="true">One</button>
<button toggle type="two" value="false">Two</button>

Kostas Jan 08 2021 at 20:11
  1. Bởi vì người nghe liên kết với giá trị cuối cùng của $ toggle.
  2. Bằng cách tạo và chạy một chức năng mới như được hiển thị trong đoạn mã.

Giải thích tốt hơn trong câu hỏi này .

<html lang="en">
    
    <head>
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        <script>
            $(() => {
                $(`button[toggle]`).each((_, button) => { let $toggle = $(button); type = $toggle.attr("type");
                    value = $toggle.attr("value"); $toggle.on("click", ((type, value) => {
                      return () => {
                        console.log(type, value);
                      };
                    })(type, value));
                });
            });
        </script>
    
    </head>
    
    <body>
        <div>
            <button toggle type="one" value="true">One</button>
            <button toggle type="two" value="false">Two</button>
        </div>
    </body>
    
    </html>