Gleno
Gleno

Reputation: 16949

Protect unspecified Javascript event handlers from being garbage collected

Recently I posed a question, asking why some of my javascript code was misbehaving. However, the accepted answer didn't fully solve my problem, so here I am once again.

Problem Description

So my question is how to protect such bound events from being garbage collected, when I temporarily tinker with the DOM?

NB! I can't do display:none to hide the <div> instead, because the whole business with deleting html content and restoring it later is handled by an unnamed jquery plugin. Nor can I call buttonset() again, because a) the graphic style gets messed up, and b) there are other controls in my real problem that don't have this handy functionality. So what I really need is some way to protect all those handlers while the elements which behavior they are supposed to govern are temporarily missing from the DOM.

Sample Code

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);
        }
    )
});

Playable Version

See this jsFiddle

Solution

I used the idea in the accepted answer to save html contents before applying buttonset(), then reapply buttonset() each time as needed on that saved data.

Upvotes: 0

Views: 165

Answers (1)

Mrchief
Mrchief

Reputation: 76208

Update:

Here's an updated fiddle that's pretty close to what your OP is. The basic idea is it destroys the buttonset to get the original html back

$(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();
        }

    })
});

Upvotes: 2

Related Questions