闭包级别局部变量存储DOM元素的风险

在闭包中编写js有很多好处,最大的好处就是可以一直保存上下文,因此许多js插件都是在闭包中编写的。例如:

 var a = (function() {
     var content = $("#content");
     var dis = function() {
         console.log(content);
         content.css("background-color", "yellow");
     };
     return {
         "dis": dis
     };
 })();

上述写法就是在闭包中封装了对于DOM元素的操作,在闭包一开始就把所有有可能涉及的DOM元素”#content”获取到并复制给闭包内的局部变量,当执行a.dis()时会在控制台输出该DOM元素并修改背景色为黄色。很好很规范的写法是不是?

但是在闭包中如果涉及到DOM元素的操作,并且该DOM元素在使用过程中有删除和重建的操作,上述的写法就会出问题,比如:页面上增加对于$(“#content”)[0]元素的删除和重建操作,a.dis()还能正确执行,修改div的背景色吗?

全部代码如下:

<html>

<head>
    <title>DOM操作测试</title>
    <meta charset="utf-8">
    <script type="text/javascript" src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
    <script>
    $(document).ready(function() {
        var a = (function() {
            var content = $("#content");
            dis = function() {
                console.log(content[0]);
                content.css("background-color", "yellow");
            };
            return {
                "dis": dis
            };
        })();
        $("#btn2").click(function() {
            $("#main").empty();
        });
        $("#btn3").click(function() {
            $("#main").html('<div id="content" style="width:100px;height:100px;background:black"></div>');
        });
        $("#btn1").click(function() {
            a.dis();
        });
    })
    </script>
</head>

<body class="body">
    <div id="main">
        <div id="content" style="width:100px;height:100px;background:black"></div>
    </div>
    <input id="btn1" type="button" value="修改DOM" />
    <input id="btn2" type="button" value="删除DOM" />
    <input id="btn3" type="button" value="增加DOM" />
</body>

</html>

测试过程:

  1. 点击“修改DOM”,DIV背景变为黄色
  2. 点击“删除DOM”,DIV被删除
  3. 点击“增加DOM”,DIV又被加上
  4. 再次点击“修改DOM”,DIV背景未变化,但是控制台中a.dis()仍然能输出先前记录下的DOM元素

结论:闭包内被预先定义的DOM元素变量无法在DOM元素变化时及时更新,其相当于只存储了该DOM对象当时的快照,当DOM元素变化(删除后重建)时无法正确的指向最新的DOM元素。

上述测试标明,在闭包中涉及的DOM元素的操作需要注意,DOM对象如果是在闭包内使用局部变量预先定义好,而不是每次使用时用jquery来获取,那就需要注意这个DOM元素变化可能带来的风险,否则会发生无法预知的错误。

建议不要使用闭包级别的局部变量来存储DOM对象,而是在闭包的方法内使用局部变量来存储DOM对象,这样可以避免该风险的发生。

修改后的闭包代码:

 var a = (function() {
     dis = function() {
         var content = $("#content");
         console.log(content);
         content.css("background-color", "yellow");
     };
     return {
         "dis": dis
     };
 })();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值