jQuery source code analysis (xxi) DOM operation module to remove elements Detailed

This section talk about the operation of the module DOM elements in the deleted module, which is used to delete a node in the DOM, can be understood as the node to uninstall from the DOM tree, if the node has a binding event, we can choose these events keep or delete, delete elements of the interface has the following three:

  • empty (); removal of all the child elements matching elements. ; First remove all descendants of the elements associated data and events, to avoid memory leaks. Then remove the child element.  
  • remove (selector, keepData); removing the matching element from the selector element. ; Selector selector expression is optional, if not passed then remove all, or just remove the corresponding matching elements. keepData Optionally, indicate whether to retain the matching element and its descendant elements associated data and events
  • detach (selector); remove from the document matches the elements of the collection; but will retain the descendant elements and matching elements associated data and events, often used to remove the element into the scene of the document again later.

He said bluntly,

  • empty () will simply remove the elements of the current match
  • Element remove () sets the current matching elements in the matching parameters 1selector, if the argument is true then 2keepData save the DOM node event, or remove an event
  • detach () is a call to remove () implementation for removing elements of the current match, but will retain the data, it is a call to remove (selector, true) to achieve

 writer by: Desert QQ: 22969969

For chestnut:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
    <div>
        <h1>你好</h1>
    </div>
    <p>朋友</p>
    <button id="b1">测试1</button>
    <button id="b2">测试2</button>
    <button id="b3">测试3</button>
    <script>
        $('h1').click(function(){console.log('h1 click')});             '        $ (to h1 elements add a click event//
P ' ) .click ( function () {the console.log ( ' P the Click ' )});                // to increase a click event element P 

        // The following three buttons are to achieve h1, p shift element from the DOM tree in addition, the insert body in front of the child node, the difference is that different output information when the child node click 
        b1.onclick = function () {$ ( ' h1 of, P ' ) .remove (). prependTo ( ' body ' ) }        // click button test 1 h1 and p elements are moved to the front body child node, but then click h1 and p elements did not respond
         b2.onclick = function () {$ ( ' h1, p ' ) .remove ( ' P ' ) .prependTo ( 'body ' )}     // click button 1 after the test element h1 and p are moved to the front body child node, click the output h1, p click no output
         b3.onclick = function () {$ ( ' h1, p ' ) .detach (). prependTo ( ' body ' )}        // click button 1 after the test h1 and p elements are moved to the front body child node, click h1 and p have outputs
     </ Script > 
</ body > 
</ HTML >

Render as follows:

 DOM tree corresponding to the following:

We give h1 and p elements are bound to an event, click on each individual output: h1 click and p click ,, click the following output:

Also regardless click Test 1, Test 2 Test 3, or, h1 and p are the elements of the DOM tree and unloaded from the front body is inserted into the child node, as follows:

At this point then click the h1 and p elements will have different output:

  • For the test button for 1; p click on h1 and no output; the result of the call remove () method and not to pass parameters, so all matched elements of the event will be deleted
  • For the test button for 2; h1 click the output, click p no output; due to call remove () method when p is passed, so the event p elements are deleted, and the event h1 element is not deleted
  • For the test button for 2; p click on h1 and no output; the result of the call detach () method, the data of all the elements have been preserved, call remove (selector, true) when detach () internally to achieve, but also 2 to remove the parameter is true

 

Source code analysis


Explain the empty (), remove () and detach () prior to first introduce a jQuery API, is $ .cleanData (elems), the parameter is a collection of DOM nodes (document.getElementsByTagName may be the return value), which is used to remove binding on a jQuery DOM node event, we give chestnuts:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
    <p>Hello World</p>
    <button>测试</button>
    <script>
        $('p').click(function(){console.log('p click')});               //给P元素增加一个点击事件
        $('button').click(function(){
            $.cleanData(document.getElementsByTagName('p'))             
</ body>        })
    to button button to add a button event, called internally $ .cleanData to clear the event binding on the p element//
</ Script>
</html>

Render as follows:

When we click on the Hello World initialization console output, if you click the button and then click on the Hello World will not output, because the $ .cleanData the event of the DOM element to uninstall ., $ Cleandata achieve the following:

jQuery.extend ({ 
    cleandata: function (the elems) {             // All event data and a plurality of removable elements DOM, elems DOM element in the array is to be removed data and events. 
        var Data, ID, 
            Cache = jQuery.cache, 
            Special = jQuery.event.special, 
            deleteExpando = jQuery.support.deleteExpando; 

        for ( var I = 0, elem;! (the elems elem = [I]) = null ; I ++) {             // iterate through each element matched 
            IF (elem && jQuery.noData .nodeName [elem.nodeName.toLowerCase ()]) {         // If not set property, skip this cycle. jQuery.noData is an array, holds the name of the node does not support extended attributes.
                Continue ; 
            } 

            ID = elem [jQuery.expando];                                                 // property name, note. 1 

            IF (ID) {                                                                     // If there jQuery.expando the DOM object properties, disposed over said data. 
                = Data Cache [ID]; 

                IF (Data && data.events) {                                             // if the DOM object exists and the associated data cache contains events property described through binding event on the DOM, then removed 
                    for ( var type in Data .events) {                                         // data.events event is cached DOM element objects stored DOM element of all events 
                        if ( special[ type ] ) {                                                
                            jQuery.event.remove( elem, type );

                        // This is a shortcut to avoid jQuery.event.remove's overhead
                        } else {
                            jQuery.removeEvent( elem, type, data.handle );
                        }
                    }

                    // Null the DOM reference to avoid IE6/7/8 leak (#7054)
                    if ( data.handle ) {
                        data.handle.elem = null;
                    }
                }

                if(DeleteExpando) {                                                     // If jQuery.support.deleteExpando; return ture, i.e. browsers support extended attributes on remove DOM elements 
                    Delete elem [jQuery.expando];                                              // remove DOM element attributes jQuery.expando 

                } the else  IF (elem .removeAttribute) {                                      // if browser does not support extended attributes on the DOM element to delete, delete the call removeAttribute property 
                    elem.removeAttribute (jQuery.expando); 
                } 

                the delete cache [the above mentioned id];                                                      // delete the data cache DOM element object cache [ID] 
            } 
        } 
    }
    / * Skip * / 
})

Note 1: Information Event jQuery bind the corresponding $ .cache there, the key is the name of the corresponding DOM object jQuery.expando, that is, elem here [jQuery.expando], there are questions you can look at to explain before the event: https://www.cnblogs.com/greatdesert/p/11679334.html

cleanData is elems in the event all DOM elements delete parameters in this section empty () and remove () are based on cleanData implemented, empty () to achieve the following:

jQuery.fn.extend ({ 
    empty: function () {                                      // . All child elements removed from the document matching elements 
        for ( var I = 0, elem; (elem = the this ! [I]) = null ; I ++) {             // through each element of current match 
            // the Remove element Nodes and Prevent Memory leaks 
            IF (elem.nodeType ===. 1 ) { 
                jQuery.cleanData (elem.getElementsByTagName ( "*"));                 // // first shift in addition to all the descendants of the elements associated data and events, to avoid memory leaks 
            }      

            // the Remove the any Remaining Nodes 
            the while(Elem.firstChild) {                                      // then removed subelements. 
                elem.removeChild (elem.firstChild); 
            } 
        } 

        return  the this ; 
    }, 
})

empty () within the first call cleandata () Removes all descendant nodes of data and events, and then uninstall each cycle through a DOM node while (), is better understood and Kazakhstan, for remove (), the realization of the following:

jQuery.fn.extend ({ 
    the Remove: function (selector, keepData) {              // remove from the selector element matching elements, the method will traverse the set of matched elements, first delete data and events descendant elements and matching elements, in order to avoid memory leak, then removed matching elements. 
        for ( var I = 0, elem; (elem = the this [I]) =! null ; I ++) {                  // iterate current matching elements 
            IF ! (|| jQuery.filter Selector (Selector, [elem]) .length) {         // If no incoming selector parameter or parameters passed in the selector, and matching the current element 
                IF (! && elem.nodeType === keepData. 1) {                                 // If no incoming keepData parameter is an element node and elem
                    jQuery.cleanData (elem.getElementsByTagName ( "*"));                         // remove all descendant elements of data and events 
                    jQuery.cleanData ([elem]);                                             // remove element node. 
                } 

                IF (elem.parentNode) {                                                 // call to native method removeChild () to remove the node. 
                    elem.parentNode.removeChild (elem); 
                } 
            } 
        } 

        return  the this ; 
    }, 
    the detach: function (Selector) {
         return  the this .remove (Selector,to true );             // call to remove () implemented, the parameters passed 2 to true 
    }, 
})

remove () method can be selected according to selector matching elements, and the matching element unloaded from the DOM tree, if there is an incoming keepData then save the data, or delete data, to detach, it is to call remove () to achieve

Guess you like

Origin www.cnblogs.com/greatdesert/p/11813539.html