Difference between Contents() and html() methods

Asked

Viewed 218 times

3

I needed to get the contents of a iframe (which was in the same domain on the same page) with html(), but to no avail.

Then I saw that there was a method called contents(), and worked out using it.

Because one gave and the other did not?

I tried to read about it, but it didn’t get into my head...

1 answer

7


We can observe in the documentation of each method that:

  • .contents()

    Collects the children of each element of the combined set of elements, including text and comment nodes.

    And also the note:

    The method .contents() can also be used to obtain the content document from a iframe, if the iframe is in the same domain as the main page.

  • .html()

    Fetch the HTML content of the first element in the combined element set or define the HTML content of each corresponding element.

Summary

Essentially, the method .contents(), is attentive to the special needs of a iframe and makes use of its property contentDocument to extract the contents if the element is actually an iframe. The method .html() does not carry out such checks and/or use of special properties of the elements.

For details, continue reading...

To iframe

To know the reason for the method .contents() be able to collect what is inside the iframe and the method .html() No, we need to look at various details about how everything works:

W3C - 5. XHTML Abstract Modules

We can see in the documentation for the abstraction modules, particularly in section 5.13 on the module iframe that it has two types of implementations: DTD and XML Schema. The relevant for this case is the DTD implementation that presents the following structure for the module iframe:

<!-- ...................................................................... -->
<!-- XHTML IFrame Module  ................................................. -->
<!-- file: xhtml-iframe-1.mod

     This is XHTML, a reformulation of HTML as a modular XML application.
     Copyright 1998-2005 W3C (MIT, ERCIM, Keio), All Rights Reserved.
     Revision: $Id: xhtml-iframe-1.mod,v 4.0 2001/04/02 22:42:49 altheim Exp $ SMI

     This DTD module is identified by the PUBLIC and SYSTEM identifiers:

       PUBLIC "-//W3C//ELEMENTS XHTML Inline Frame Element 1.0//EN"
       SYSTEM "http://www.w3.org/MarkUp/DTD/xhtml-iframe-1.mod"

     Revisions:
#2000-10-22: added #PCDATA to <iframe> content model as per HTML 4
     ....................................................................... -->

<!-- Inline Frames

        iframe

     This module declares the iframe element type and its attributes,
     used to create an inline frame within a document.
-->

<!-- Inline Frames .................................... -->

<!ENTITY % iframe.content  "( #PCDATA | %Flow.mix; )*" >
<!ENTITY % iframe.qname  "iframe" >
<!ELEMENT %iframe.qname;  %iframe.content; >
<!ATTLIST %iframe.qname;
      %Core.attrib;
      longdesc     %URI.datatype;           #IMPLIED
      src          %URI.datatype;           #IMPLIED
      frameborder  ( 1 | 0 )                '1'
      marginwidth  %Pixels.datatype;        #IMPLIED
      marginheight %Pixels.datatype;        #IMPLIED
      scrolling    ( yes | no | auto )      'auto'
      height       %Length.datatype;        #IMPLIED
      width        %Length.datatype;        #IMPLIED
>

<!-- end of xhtml-iframe-1.mod -->

And going back to the previous page, we can read:

When this module is used, the element iframe is added to the online content set as defined by Text module.

And this essentially answers the question, any text element has no child nodes, hence the method .html() can’t collect anything from them.

Already the method .contents(), by collecting whatever is inside the element, collects what is inside the iframe for an object. This allows us to subsequently access the information present in the resulting object.

Examples

$('#sample1').click(function() {
  // devolve um objeto, mesmo só existindo texto na DIV
  alert($("div").contents());
});

$('#sample2').click(function() {
  // devolve um objeto, e depois "undefined" porque não existem nós para poder trabalhar
  alert($("div").contents().html());
});

$('#sample3').click(function() {
  // recolhe um objeto, e devolve o seu texto
  alert($("div").contents().text());
});

$('#sample4').click(function() {
  // devolve texto pois está a trabalhar num nó
  alert($("div").html());
});

$('#sample5').click(function() {
  // devolve texto
  alert($("div").text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div>A minha div é muito bonita!</div>
<p>
  <button id="sample1">.contents()</button>
  <button id="sample2">.contents().html()</button>
  <button id="sample3">.contents().text()</button>
  <button id="sample4">.html()</button>
  <button id="sample5">.text()</button>
</p>
<em>clica nos botões para usar os métodos descritos nos mesmos.</em>

But what does jQuery

What remains to be seen in jQuery code to justify the ability of .contents() in relation to iframe, where for this purpose we observe its code, particularly line 3040 to 3044:

contents: function( elem ) {
    return jQuery.nodeName( elem, "iframe" ) ?
        elem.contentDocument || elem.contentWindow.document :
        jQuery.merge( [], elem.childNodes );
}

We easily observe that the method .contents() makes an analysis of the element where it is working to see if it is a iframe, and if so, will invoke the property contentDocument of the element iframe, which is responsible for returning the content of the iframe.

Note: contentWindow.document is an equivalence to IE8.

Already the method .html() is completely oblivious to the special requirements of a iframe, as we can ascertain in jQuery source code from line 5842 to 5882:

html: function( value ) {
    return access( this, function( value ) {
        var elem = this[ 0 ] || {},
            i = 0,
            l = this.length;

        if ( value === undefined ) {
            return elem.nodeType === 1 ?
                elem.innerHTML.replace( rinlinejQuery, "" ) :
                undefined;
        }

        // See if we can take a shortcut and just use innerHTML
        if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
            ( support.htmlSerialize || !rnoshimcache.test( value )  ) &&
            ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
            !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {

            value = value.replace( rxhtmlTag, "<$1></$2>" );

            try {
                for (; i < l; i++ ) {
                    // Remove element nodes and prevent memory leaks
                    elem = this[i] || {};
                    if ( elem.nodeType === 1 ) {
                        jQuery.cleanData( getAll( elem, false ) );
                        elem.innerHTML = value;
                    }
                }

                elem = 0;

            // If using innerHTML throws an exception, use the fallback method
            } catch(e) {}
        }

        if ( elem ) {
            this.empty().append( value );
        }
    }, null, value, arguments.length );
},

Browser other questions tagged

You are not signed in. Login or sign up in order to post.