Удаляет ли replaceWith() в jQuery также обработчики событий?

#jquery

#jquery

Вопрос:

Я просмотрел документацию jQuery для ответа на этот простой вопрос:

replaceWith() Вызывает remove() или detach() под капотом?

Мне не повезло с официальной документацией; это двусмысленно определяется как удаление узла. Но тесты показывают утечку памяти.

Ответ №1:

Глядя на исходный код jQuery (2.1.1), вы задаете два разных вопроса.

  1. replaceWith() Удаляет ли jQuery обработчики событий?

    Да. jQuery вызывает cleanData() внутренний метод, который удаляет все данные в элементе. Поскольку обработчики событий jQuery хранятся в данных элементов, они также будут очищены.

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

  2. replaceWith() Вызывает remove() или detach() под капотом?

    Единственный раз, когда он вызывается remove() , — это если для replaceWith() не было предоставлено аргументов; jQuery обрабатывает это так, как если бы вы вызывали remove() вместо replaceWith() ;


TL;DR: jQuery все очистит для вас, поэтому не должно быть риска утечек памяти.

Ответ №2:

FYW если вы не хотите такого поведения, взгляните на этот плохо обсуждаемый поток по билетам jQueryhttp://bugs.jquery.com/ticket/13400

и для тех, кто не готов ожидать код, вот реализация, replaceWith которая использует detach вместо remove

с помощью remove()

old.replaceWith( new );

с помощью detach()

old.before( new ).detach();

Ответ №3:

1) с помощьюA.replaceWith(B); это удалит элемент A и все прикрепленные события. Все события для B должны быть объявлены

2) с помощьюA.перед(B ).detach(); это удалит элемент A, но сохранит событие на потом (и снова будет применяться только к A). Все события для B должны быть объявлены

Эта проблема может быть решена с помощью распространения событий или пузырьковой обработки событий, как в приведенном ниже коде

 <!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){ 
  $(".rp").click(function(){
    let variable1 = parseInt($(this).text(), 10)   6;
    $(this).replaceWith("<button class='rp'>"  variable1   "</button>");

   });

   $(".detach").click(function(){
    let variable1 = parseInt($(this).text(), 10)   6;
    $(this).replaceWith("<button class='detach'>"  variable1   "</button>");

   });

   $("body").on("click", ".detach2",function(){
    let variable1 = parseInt($(this).text(), 10)   6;
    $(this).replaceWith("<button class='detach2'>"  variable1   "</button>");
   });

   $("body").on("click", ".detach3",function(){
    let variable1 = parseInt($(this).text(), 10)   6;
    $(this).before("<button class='detach3'>"  variable1   "</button>"). detach();
   });

});
</script>
</head>
<body>

<h1>This is a heading</h1>

<p>with ReplaceWith <button class="rp">1</button></p>
<p>with before / detach <button class="detach">2</button> </p>
<p>with ReplaceWith correct event bubbling <button class="detach2">3</button> </p>
<p>with before / detach and correct event bubbling <button class="detach3">4</button> </p>

</body>
</html>
  

Надеюсь, что это может кому-то помочь…