PHP程序员站--PHP编程开发平台
 当前位置:主页 >> 网页制作 >> Javascript >> 

jquery innerHTML使用注意

jquery innerHTML使用注意

来源:PHP程序员站  作者:PHP程序员站  发布时间:2011-06-25
核心提示:jquery innerHTML使用不当会导致内存泄露 问题代码: !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd html head meta content=text/html;charset=utf-8 http-equiv=content-type / s

核心提示:jquery innerHTML使用不当会导致内存泄露

问题代码:
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html> 
    <head> 
        <meta content="text/html;charset=utf-8" http-equiv="content-type" /> 
        <script src="jquery-1.3.2.js" type="text/javascript"> 
        </script> 
        <style type="text/css"> 
            #inner {  
                margin:0 auto;  


                width:150px;  
                height:50px;  
                border:1px solid green;  
            }  
        </style> 
        <script type="text/javascript"> 
        $(function(){  
            $("#inner").click(function(){  
                //错误,引起内存泄露  
                $("#test")[0].innerHTML="";  

                  
                //正确做法  
                //$("#test").empty();  
            });  
              
        });  
        </script> 
        <title>测试</title> 
    </head> 
    <body> 
        <div style="height:500px;width:500px;border:1px solid red;padding-top:100px;" id="test"> 
            <div id="inner">click to remove me</div> 
        </div>      
    </body> 
</html> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
 <head>
  <meta content="text/html;charset=utf-8" http-equiv="content-type" />
  <script src="jquery-1.3.2.js" type="text/javascript">
  </script>
  <style type="text/css">
   #inner {
    margin:0 auto;
    width:150px;
    height:50px;
    border:1px solid green;
   }
  </style>
  <script type="text/javascript">
  $(function(){
   $("#inner").click(function(){
    //错误,引起内存泄露


    $("#test")[0].innerHTML="";
    
    //正确做法
    //$("#test").empty();
   });
   
  });
  </script>
  <title>测试</title>
 </head>
 <body>
  <div style="height:500px;width:500px;border:1px solid red;padding-top:100px;" id="test">
   <div id="inner">click to remove me</div>
  </div> 
 </body>
</html>

场景:

inner div 就是常见的我们可能使用 ajax 从服务器动态构造的元素,或者注入的片断html,效果为点击 inner 后就把它以及它的兄弟清除出去,依照传统的思路,直接innerHTML =“” 就好了 ,可能你会想到所有删除元素的事件监听器应该清楚掉,但是对于除了 ie6 (引起内存泄露)以外的浏览器,清除事件监听器不是必要的 。

jquery 机制:

但是可以确定的是在 jquery 中用 innerHTML 的方法来清空元素,是必然会导致内存泄露的,由于 jquery 对于同一元素多事件处理没有直接采用浏览器事件模型,而是自己缓存事件,遍历触发,以及便于 trigger 程序触发 :

// Init the element's event structure  
        var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),  
            handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){  
                // Handle the second event of a trigger and when  
                // an event is called after a page has unloaded  
                return typeof jQuery !== "undefined" && !jQuery.event.triggered ?  
                    jQuery.event.handle.apply(arguments.callee.elem, arguments) :  
                    undefined;  
            }); 

// Init the element's event structure
  var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
   handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
    // Handle the second event of a trigger and when
    // an event is called after a page has unloaded
    return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
     jQuery.event.handle.apply(arguments.callee.elem, arguments) :
     undefined;
   }); 
采用 data 方法,将一些数据关联到了元素上面,上述事件即是采用该机制缓存事件监听器。

那么就可以知道,直接 innerHTML=“” 而不通知 jquery 清空与将要删除元素关联的数据,那么这部分数据就再也释放不了了,即为内存泄露。

解决:

jquery 已经想到了这一方面,提供了 empty 函数,其思想就是,对节点的所有子,孙,重孙.....节点( $("*",this) ),先清空它们关联的数据,再进行节点的删除:

remove: function( selector ) {  
        if ( !selector || jQuery.filter( selector, [ this ] ).length ) {  
            // Prevent memory leaks  
            jQuery( "*", this ).add([this]).each(function(){  
                jQuery.event.remove(this);  
                jQuery.removeData(this);  
            });  
            if (this.parentNode)  
                this.parentNode.removeChild( this );  
        }  
    },  
 
    empty: function() {  
        // Remove element nodes and prevent memory leaks  
        jQuery(this).children().remove();  
 
        // Remove any remaining nodes  
        while ( this.firstChild )  
            this.removeChild( this.firstChild );  
    } 


延伸阅读:
ajax入门简明教程---innerHTML属性
Tags: jQuery   innerHTML  
最新文章
推荐阅读
月点击排行榜
PHP程序员站 Copyright © 2007-2010,PHPERZ.COM All Rights Reserved 粤ICP备07503606号