In the Decoding jQuery series,
we will break down every single method in jQuery, to study the beauty
of the framework, as an appreciation to the collective/creative geniuses
behind it.
Inside manipulation.js within the jQuery source, there is an interesting internal method named
Using fragment
In
If we’re in a fragment, just use it, otherwise, building a new one using
jQuery.buildFragment
Let’s take out
1. nodes may contain either an explicit document object, a jQuery collection or context object. The following checks if nodes[0] contains a valid object to assign to doc
2. Ensure that an attr object doesn’t incorrectly stand in as a
document object, Chrome and Firefox seem to allow this to occur and will
throw exception
With the above check, the script will then fragment
3. To check if an element is cacheable. The method only caches
“small” (1/2 KB) HTML strings that are associated with the main
document. Cloning options loses the selected state, so it doesn’t cache
them. IE 6 doesn’t like it when you put
The following script does the caching once it’s determined cacheable:
Appending script
I first discovered this while inserting a
This check does 4 things here:
1. first it detects and loop through all the script elements
2. if the script element has a
3. if the script is embedded, jQuery uses jQuery.globalEval to evaluate the script
4. it removed the child from the parent element
Inside manipulation.js within the jQuery source, there is an interesting internal method named
domManip
, this is mainly used for methods like: .append()
, .prepend()
, .before()
and .after()
.domManip: function( args, table, callback ) { //... }
In
domManip
, jQuery first checks if we are dealing with fragment node. In DOM, there are 12 different node types, and the one jQuery is checking is type 11 (Node.DOCUMENT_FRAGMENT_NODE == 11
).If we’re in a fragment, just use it, otherwise, building a new one using
jQuery.buildFragment
.
if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { results = { fragment: parent }; } else { results = jQuery.buildFragment( args, this, scripts ); }
Let’s take out
jQuery.buildFragment
and see what it does. The method comes with excellent explanation that talks about what each block of code does:1. nodes may contain either an explicit document object, a jQuery collection or context object. The following checks if nodes[0] contains a valid object to assign to doc
if ( nodes && nodes[0] ) { doc = nodes[0].ownerDocument || nodes[0]; }
if ( !doc.createDocumentFragment ) { doc = document; }
if ( !fragment ) { fragment = doc.createDocumentFragment(); jQuery.clean( args, doc, fragment, scripts ); }
object
or embed
elements in a fragment. Also, WebKit does not clone ‘checked’
attributes on cloneNode, so it doesn’t cache them either. Lastly, IE6,
7, 8 will not correctly reuse cached fragments that were created from
unknown elements.if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document && first.charAt(0) === "<" && !rnocache.test( first ) && (jQuery.support.checkClone || !rchecked.test( first )) && (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { cacheable = true; cacheresults = jQuery.fragments[ first ]; if ( cacheresults && cacheresults !== 1 ) { fragment = cacheresults; } }
if ( cacheable ) { jQuery.fragments[ first ] = cacheresults ? fragment : 1; }
I first discovered this while inserting a
script
tag using jQuery and inspect the element without seeing this. This is because within the domManip
, there is a check for script elements.if ( scripts.length ) { jQuery.each( scripts, function( i, elem ) { if ( elem.src ) { jQuery.ajax({ type: "GET", global: false, url: elem.src, async: false, dataType: "script" }); } else { jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); } if ( elem.parentNode ) { elem.parentNode.removeChild( elem ); } }); }
1. first it detects and loop through all the script elements
2. if the script element has a
src
attribute, then jQuery uses jQuery ajax to load the script3. if the script is embedded, jQuery uses jQuery.globalEval to evaluate the script
4. it removed the child from the parent element
Nessun commento:
Posta un commento