Czy muszę odłączyć Zdarzenie jquery przed usunięciem elementu?

Mam stronę używającą jQuery-UI-dialog. Za każdym razem, gdy otwiera się okno dialogowe, zawartość strony ładuje się za pomocą ajax. Następnie wiąże jakieś zdarzenie używając jquery " on ()". Po zamknięciu okna dialogowego zostanie opróżniona jego zawartość.

Pytanie brzmi , Czy muszę odpiąć wydarzenia na ".ajax-content " przed $.pusta()?

edit : troska 1. jakieś możliwe pogorszenie wydajności JS? jeśli opróżnię () setki węzłów w ten sposób.

troska 2. would Usuń element również Usuń zdarzenia z pamięci (lub jakikolwiek łańcuch wykonania/oceny jquery)?

Na razie nic im nie zrobię. Jeśli okno dialogowe otwiera / zamyka się wiele razy bez odświeżania strony, czy spowoduje to jakiś problem?

Kod wygląda tak:

<div id="jquery-dialog" class="container">
  <div class="ajax-content">
    some buttons....
  </div>
</div>

------after each ajax load------------
$(".ajax-content").on("click", ".button", function(event) {
  //handles the click
});

------on dialog close------------
$("#jquery-dialog").empty();
Author: Reed, 2012-06-09

3 answers

Hej wiem, że to stara odpowiedź, ale uważam, że przyjęta odpowiedź jest myląca.

Chociaż prawdą jest, że będziesz musiał usunąć zdarzenia na raw JS, aby uniknąć wycieków pamięci w starych przeglądarkach (ehem IE), wywołanie remove () lub empty () już to zrobi za Ciebie.

Więc twoje obecne wywołanie empty powinno wystarczyć, nie musi być poprzedzone unbind ()

From jQuery docs ( http://api.jquery.com/empty/)

Aby uniknąć wycieków pamięci, jQuery usuwa inne konstrukcje, takie jak procedury obsługi danych i zdarzeń z elementów potomnych przed usunięciem samych elementów.

 45
Author: Oscar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-17 20:07:54

Lepiej odpiąć, ale trzeba.

Większość przeglądarek obsługuje to poprawnie i usuwa te programy obsługi.

Możesz również zobaczyć do-I-need-to-remove-event-listeners

Lepszy sposób radzenia sobie z tym problemem, możesz użyć delegata zdarzenia.

 1
Author: Liber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:25

Odpowiedź Oscara jest niekompletna, jeśli wewnątrz twojego częściowego (widok ładowany przez ajax) załączasz zdarzenia za pomocą .on (), następnie musisz zadzwonić .off () przed .empty().

Spójrz w poniższy kod, jeśli .off () nie jest wywoływana, zdarzenia przypisane w p1.html poprzez standard .obsługa Click() jest usuwana podczas wywołania .empty (), ale zdarzenia przypisane w p2.html via .on () nie są usuwane i ponownie przypisywane za każdym razem, gdy część jest załadowany.

Indeks.html

<html>
<body>
<script src="ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
    <div id='spi' style="padding: 20px; border: 1px solid #666;">
    </div>
    <br/>
    <a href="p1.html" class="spi">Load Partial 1</a> | 
    <a href="p2.html" class="spi">Load Partial 2</a>
    <script type="text/javascript">
    $(document).on('click', 'a.spi' , function(e) {
        e.preventDefault();

        /* 
        !!! IMPORTANT !!!
        If you do not call .off(), 
        events assigned on p2.html via .on()
        are kept and fired one time for each time p2.html was loaded
        */

        $("#spi").off();  


        $("#spi").empty();
        $("#spi").load($(this).attr('href'));
    });
    </script>
</body>
</html>

P1.html

This is the partial 1<br/>
<br/>
<br/>
<a href="javascript:void(0)" id='p1_l1'>Link 1</a>
<br/><br/>
<a href="javascript:void(0)" id='p1_l2'>Link 2</a>
<br/><br/>
<a href="javascript:void(0)" id='p1_l3'>Link 3</a>


<script type="text/javascript">
    $("#p1_l1").click(function(e) {
        e.preventDefault();
        console.debug("P1: p1_l1");
    });
    $("#p1_l2").click(function(e) {
        e.preventDefault();
        console.debug("P1: p1_l2");
    });
</script>

P2.html

This is the partial 2<br/>
<br/>
<br/>
<a href="javascript:void(0)" id='p2_l1'>Link 1</a>
<br/><br/>
<a href="javascript:void(0)" id='p2_l2'>Link 2</a>


<script type="text/javascript">
    $("#spi").on('click', 'a', function(e) {
        e.preventDefault();
        console.debug( 'P2: ' + $(this).attr('id') );
    });
</script>
 -1
Author: maxidirienzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-10 12:34:15