Jak dodać poszczególne detektory zdarzeń za pomocą jquery .each ()?

Jan 08 2021

Mam prostą konfigurację: dwa przyciski z różnymi wartościami. Chcę użyć funkcji .each () z jquery, aby dodać detektor zdarzeń kliknięcia do każdego z przycisków, który po prostu rejestruje wartości każdego przycisku. Ale w jakiś sposób podczas używania .each () jquery nadpisuje moduł obsługi kliknięcia dla poprzedniego przycisku (ów). Pozostają mi dwa pytania:

  1. Dlaczego?
  2. Jak dodać poszczególne detektory zdarzeń do kolekcji obiektów jquery?

Zobacz kod poniżej

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

Odpowiedzi

1 RoryMcCrossan Jan 08 2021 at 20:14

Problem w twoim kodzie polega na tym, że niejawnie zadeklarowałeś zmienne typei value, więc są one windowobjęte zakresem. W związku z tym każda następna iteracja nadpisuje wartości, tak że po zakończeniu pętli widoczne są tylko wartości końcowe.

Aby to naprawić, zdefiniuj zmienne w pętli:

$(() => { $(`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>

Jednakeach() pętla w ogólenie jest potrzebna. Możesz rozwiązać problem i poprawić jakość kodu, wiążąc tę ​​samą procedurę obsługi zdarzeń ze wszystkimibuttonelementami i używająctargetwłaściwości zdarzenia, które jest wywoływane, w celu uzyskania dostępu do ich atrybutów.

Ponadto pamiętaj, że dodanie własnych niestandardowych atrybutów togglew tym przypadku może prowadzić do problemów w interfejsie użytkownika i JS. Lepszym podejściem jest użycie klasy do grupowania elementów.

Wreszcie onei twonie są prawidłowymi wartościami typeatrybutu. dataZamiast tego użyj atrybutu, aby dołączyć własne niestandardowe metadane do elementu.

Biorąc to wszystko pod uwagę, spróbuj tego:

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

użyj $(this)wewnątrz wywołania zwrotnego kliknięcia

$(() => {
  $(`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>

A także nie trzeba wspominać w każdym wywołaniu zwrotnym. Możesz zadzwonić w normalny sposób, jak poniżej

$(() => { $(`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. Ponieważ detektor wiąże się z ostatnią wartością $ toggle.
  2. Tworząc i uruchamiając nową funkcję, jak pokazano we fragmencie.

Wyjaśniono lepiej w tym pytaniu .

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