Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Течёт память из-за обработчиков на удалённых объектах (https://javascript.ru/forum/events/71669-techjot-pamyat-iz-za-obrabotchikov-na-udaljonnykh-obektakh.html)

Petrov R 04.12.2017 19:15

Течёт память из-за обработчиков на удалённых объектах
 
Добрый день Уважаемые!

Помогите мне разобраться пожалуйста.
Использую такого рода схему:
<html>
<body>
<div listen="my.action">...</div>
</body>
</html>

// После загрузки странички инициализируем обработчики
$(document).ready(function() {
   listenersInit();
});

function listenersInit(){
     //Для всех элементов с указанным набором атрибутов вешаем обработчики
     $("[listen][bn!=1]").each(function(){
              //Обработчик на click
              $(this).click(function(){ .....DO SOMETHING....});

              //Помечаем объект что на нём уже висит обработчик, чтобы повторно не вешать
              $(this).attr("bn", 1);

              return true;
     });

     return true;
}


Так вот проблема возможно в том, что при всяких ajax запросах, на страничке какие-то элементы и даже группы элементов удаляются или заменяются другими блоками кода по типу: obj.innerHTML="......";
и после этих ajax запросов вызывается функция listenersInit(), которая снова пробегает по элементам с не навешанными обработчиками и вешает на них.

Так вот проблема как я думаю в том, что когда элементы с обработчиками удаляются, то сами то обработчики никуда не деваются, а как их учесть я что-то ума не приложу.

Подскажите мне 2 вещи пожалуйста:
1. Удобный и понятный инструментарий для анализа того, что течёт на странице.
2. Как подобные ситуации разруливаете вы?

В плане инструментария, прошу учесть что у меня на машине стоит *никс, а в инете находил рекоммендации решения проблем с утечками в Visual Studio, мне это точно не подходит.

Спасибо!

MallSerg 04.12.2017 20:58

профилирование

Nexus 05.12.2017 09:51

Вы вешаете обработчики через jq (а он их кеширует), далее удаляете их используя свойство "innerHTML", а кеш остается.
Используйте вместо свойства "innerHTML", например, jq метод "html".
Кеш jq хранится тут: $.cache

Dilettante_Pro 05.12.2017 10:31

Petrov R,
Можно вешать обработчики на родителей, которые постоянно находятся на странице, и не навешивать новые на динамически создаваемые-удаляемые элементы.

Petrov R 05.12.2017 13:33

Спасибо за ответы!

Я в итоге поставил хром и на ночь оставил свою прогу. Перед этим сделал снапшот состояния памяти в хроме. И утром, в итоге новых объектов насоздавалось. Но уже меньше.

Я в своём этом javascript'е везде все переменные в функциях инициализировал как var varname. А то до этого я к этому относился более небрежно, а тут рыть стал так оказывается в функции если не объявлена переменная, то она становится глобальной.

И про отличие innerHTML от html("") тоже прочитал, сейчас вот сделал чтобы перезапись элментов DOM везде была через html().

Хотел посмотреть содержимое $.cache но в консоли говорит на вариант:
console.log(JSON.stringify($.cache));
не работает.

Поделитесь может ещё советами по особенностям написания кода и избегания утечек памяти?

Nexus 05.12.2017 13:55

Petrov R, в консоль необязательно строки передавать, она адекватно воспринимает любые типы данных.
Т.е. можно так:
console.log($.cache);

MallSerg 05.12.2017 21:30

Цитата:

Сообщение от Nexus (Сообщение 472078)
Petrov R, в консоль необязательно строки передавать, она адекватно воспринимает любые типы данных.
Т.е. можно так:
console.log($.cache);

иногда лучше console.dir($.cache)
console.log (document); отображает html
console.dir (document); отображает объектную модель
https://developer.mozilla.org/ru/doc...PI/Console/log


Часовой пояс GMT +3, время: 13:21.