Защитите неуказанные обработчики событий Javascript от сбора мусора - PullRequest
0 голосов
/ 12 августа 2011

Недавно я задал вопрос , спрашивающий, почему некоторые из моих javascript-кодов плохо себя ведут. Однако принятый ответ не полностью решил мою проблему, поэтому я снова здесь.

Описание проблемы

  • У меня есть <div>, в котором есть коллекция переключателей.
  • Я использую jquery ui для стилизации этой коллекции с помощью buttonset(). Это выглядит резонно красиво.
  • Затем я очищаю <div> с помощью jquery, делая что-то с эффектом $("#mydiv").html("")
  • Затем я снова восстанавливаю точное содержимое, которое было удалено.
  • Наконец, buttonset больше не работает должным образом, потому что его события были отключены в процессе.

Итак, мой вопрос как защитить такие связанные события от сбора мусора, когда я временно возиться с DOM?

NB! Я не могу display:none скрыть вместо <div>, потому что весь бизнес с удалением html-контента и его последующим восстановлением обрабатывается неназванным плагином jquery. Также я не могу снова вызвать buttonset(), потому что а) графический стиль испорчен, и б) в моей реальной задаче есть другие элементы управления, которые не имеют такой удобной функциональности. Так что мне действительно нужен какой-то способ защиты всех этих обработчиков, в то время как элементы, поведение которых они должны управлять, временно отсутствуют в DOM.

Пример кода

HTML

<div id="container">
    <div id="buttonset">
        <input type="radio" id="radio1" name="option" />
        <label for="radio1">X</label>
        <input type="radio" id="radio2" name="option" />
        <label for="radio2">Y</label>
        <input type="radio" id="radio3" name="option" />
        <label for="radio3">Z</label>
    </div>
</div>

<div id="control">
    <input id="toggle" type="checkbox"/>
    <label for="toggle">Toggle</label>
</div>

Javascript

$(function(){
    $("#buttonset").buttonset();  
    $("#toggle").click(
        function(){
            if($(this).is(":checked"))
            {
                backup = $("#container").html();
                $("#container").html("");
            } else $("#container").html(backup);
        }
    )
});

Воспроизводимая версия

Смотрите это jsFiddle

Решение

Я использовал идею в принятом ответе, чтобы сохранить html-содержимое перед применением buttonset(), а затем повторно применять buttonset() каждый раз, когда это необходимо для сохраненных данных.

1 Ответ

2 голосов
/ 12 августа 2011

Обновление:

Вот обновленная скрипка , которая довольно близка к вашей ОП. Основная идея состоит в том, чтобы destroys buttonset вернуть исходный html

$(function() {    

    //Turn the radio buttons into a jquery ui buttonset
    $("#buttonset").buttonset();

    //Use the toggle button to hide/show the #container div.
    //NB! It's not possible to do css display:none instead,
    //due to some other limitations, to wit, I'm using a
    //library that I can not modify.
    $("#toggle").button();

    var backup;      // added this to prevent it from leaking onto global scope.

    $("#toggle").click(function() {
        if ($(this).is(":checked")) {

            // restore the html back
            $("#buttonset").buttonset("destroy");

            backup = $("#container").html();
            $("#container").html("");
        } 
        else { 
            $("#container").html(backup);
            $("#buttonset").buttonset();
        }

    })
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...