保护未指定的 Javascript 事件处理程序不被垃圾收集

发布于 2024-11-29 10:13:02 字数 2147 浏览 1 评论 0原文

最近,我提出了一个问题,询问为什么我的一些 javascript 代码行为不当。然而,接受的答案并没有完全解决我的问题,所以我再次来到这里。

问题描述

  • 我有一个
    ,其中有一组单选按钮。
  • 我使用 jquery ui 通过 buttonset() 来设置该集合的样式。它看起来相当漂亮。
  • 然后我用jquery清空了
    ,通过执行一些达到$("#mydiv").html("")的效果
  • 然后我再次恢复< em>确切已删除的内容。
  • 最后,按钮集不再正常工作,因为它的事件在此过程中变得混乱。

所以我的问题是当我临时修改 DOM 时,如何保护此类绑定事件不被垃圾收集?

注意! 我不能做 display:none 来隐藏

,因为删除 html 内容并稍后恢复它的整个业务是由一个未命名的 jquery 插件处理的。我也不能再次调用 buttonset(),因为 a) 图形样式变得混乱,b) 在我的实际问题中还有其他控件没有这种方便的功能。所以我真正需要的是某种方法来保护所有这些处理程序,而它们应该控制的行为的元素暂时从 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

解决方案

我在接受的答案中使用了这个想法,在应用 buttonset() 之前保存 html 内容,然后每次根据需要在保存的数据上重新应用 buttonset()

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

  • I have a <div> which has a collection of radio buttons in it.
  • I use jquery ui to style that collection with a buttonset(). It looks resonably pretty.
  • Then I empty the <div> with jquery by doing something to the effect of $("#mydiv").html("")
  • Then I once again restore exact contents that were removed.
  • Finally the buttonset is no longer working properly, because its events got unhinged in the process.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花开柳相依 2024-12-06 10:13:02

更新:

这是一个更新的fiddle,它与您的OP非常接近是。基本思想是销毁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();
        }

    })
});

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

    })
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文