Подтвердить что ты не робот

Нужно ли отключать событие jquery перед удалением элемента?

У меня есть страница, использующая jquery-ui-dialog. Каждый раз, когда открывается диалог, содержимое страницы загружается с использованием ajax. Затем он связывает какое-либо событие с помощью jquery "on()". Когда диалоговое окно закроется, оно будет опущено его содержимое.

Вопрос, нужно ли отключать события на ".ajax-content" до $.empty()?

изменить: беспокоит 1. любое возможное ухудшение производительности JS? если я опустел() сотни узлов таким образом.

проблема 2. удалит элемент также удалить события из памяти (или любую цепочку выполнения/оценки jquery)?

Я пока ничего для них не делаю. Если диалог открывается или закрывается много раз без обновления страницы, это может вызвать проблемы?

Код выглядит так:

<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();
4b9b3361

Ответ 1

Эй, я знаю, что это старый ответ, но я считаю, что принятый ответ вводит в заблуждение.

Хотя правильно сказать, что вам нужно отключить события на необработанном JS, чтобы избежать утечек памяти в старых браузерах (ehem IE), вызов remove() или empty() уже сделает это для вас.

Итак, ваш текущий вызов empty() должен быть достаточным, ему не нужно предшествовать unbind()

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

Чтобы избежать утечек памяти, jQuery удаляет из дочерних элементов другие конструкторы, такие как данные и обработчики событий, перед удалением самих элементов.

Ответ 2

Лучше развязать, но нужно.

Большинство браузеров обрабатывают это правильно и сами удаляют эти обработчики.

Вы также можете увидеть do-i-need-to-remove-event-listeners

Лучший способ справиться с этой проблемой, вы можете использовать делегат Event.

Ответ 3

Ответ на Oscar не завершен, если внутри вашего частичного (просмотр, загруженный через ajax) вы подключили события с использованием .on(), тогда вы должны вызывать .off() перед .empty().

Посмотрите на следующий код, если .off() не вызывается, события, назначенные в p1.html с помощью стандартного обработчика .click(), удаляются при вызове .empty(), но события, назначенные в p2.html через .on() не удаляются и повторно назначаются каждый раз при загрузке части.

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