Browser crashes with below code.What is wrong in below code.

Discussion in 'Javascript' started by kiran, Dec 4, 2011.

  1. kiran

    kiran Guest

    Hi,

    All my browser are either hanging or crashing due to below code,Any ideas as what is happening.While debugging my jsp page, I narrowed down to below clone method of jquery.Also as per my understanding there are some tags in HTML5 which do not require to have end tags, does UL require end tag as per HTML5 ?.
    Again I am no expert in Javascript but again trying to get my hands dirty either by reading books or trying on my own by googling here and there on net.

    <!DOCTYPE HTML>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Simple Test Case</title>
    </head>

    <body>
    <ul>
    <li>Test1</li>
    <li>Test2</li>
    <li>Test3</li>
    <li>Test4</li>
    <li>Test5</li>
    <li>Test6</li>
    </ul>

    <script type="text/javascript" src="js/jquery-1.6.4.js"></script>
    <script>
    jQuery('ul').clone().appendTo('body');
    </script>
    </body>
    </html>
     
    kiran, Dec 4, 2011
    #1
    1. Advertising

  2. kiran

    kiran Guest

    This is code which crashes browsers,below code do not have end UL tag.Though having end UL fixes the crash,but wanted to get this confirmed.

    <!DOCTYPE HTML>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Simple Test Case</title>
    </head>

    <body>
    <ul>
    <li>Test1</li>
    <li>Test2</li>
    <li>Test3</li>
    <li>Test4</li>
    <li>Test5</li>
    <li>Test6</li>


    <script type="text/javascript" src="js/jquery-1.6.4.js"></script>
    <script>
    jQuery('ul').clone().appendTo('body');
    </script>
    </body>
    </html>
     
    kiran, Dec 4, 2011
    #2
    1. Advertising

  3. kiran

    Swifty Guest

    On Sat, 3 Dec 2011 21:02:49 -0800 (PST), kiran <>
    wrote:

    >This is code which crashes browsers,below code do not have end UL tag.Though having end UL fixes the crash,but wanted to get this confirmed.
    >
    ><!DOCTYPE HTML>
    ><html>
    ><head>
    ><meta charset="utf-8">
    ><title>Simple Test Case</title>
    ></head>
    >
    ><body>
    ><ul>
    ><li>Test1</li>
    ><li>Test2</li>
    ><li>Test3</li>
    ><li>Test4</li>
    ><li>Test5</li>
    ><li>Test6</li>
    >
    >
    ><script type="text/javascript" src="js/jquery-1.6.4.js"></script>
    ><script>
    >jQuery('ul').clone().appendTo('body');
    ></script>
    ></body>
    ></html>


    Having little knowledge of Javascript, and none of jQuery, this looks
    fairly obvious.

    The jQuery statement seems to be cloning your "ul" element and
    appending it to the body.

    <ul> requires a closing </ul>.

    So, the cloning starts at the <ul>, and failing to find the closing
    </ul> it clones to the end of the HTML, including the cloning request.
    The cloned jQuery statement then sets about its work, and the process
    loops until you run out of memory.

    --
    Steve Swift
    http://www.swiftys.org.uk/swifty.html
    http://www.ringers.org.uk
     
    Swifty, Dec 4, 2011
    #3
  4. kiran

    RobG Guest

    On Dec 4, 4:52 pm, Swifty <> wrote:
    > On Sat, 3 Dec 2011 21:02:49 -0800 (PST), kiran <>
    > wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > >This is code which crashes browsers,below code do not have end UL tag.Though having end UL fixes the crash,but wanted to get this confirmed.

    >
    > ><!DOCTYPE HTML>
    > ><html>
    > ><head>
    > ><meta charset="utf-8">
    > ><title>Simple Test Case</title>
    > ></head>

    >
    > ><body>
    > ><ul>
    > ><li>Test1</li>
    > ><li>Test2</li>
    > ><li>Test3</li>
    > ><li>Test4</li>
    > ><li>Test5</li>
    > ><li>Test6</li>

    >
    > ><script type="text/javascript" src="js/jquery-1.6.4.js"></script>
    > ><script>
    > >jQuery('ul').clone().appendTo('body');
    > ></script>
    > ></body>
    > ></html>

    >
    > Having little knowledge of Javascript, and none of jQuery, this looks
    > fairly obvious.
    >
    > The jQuery statement seems to be cloning your "ul" element and
    > appending it to the body.
    >
    > <ul> requires a closing </ul>.
    >
    > So, the cloning starts at the <ul>, and failing to find the closing
    > </ul> it clones to the end of the HTML, including the cloning request.
    > The cloned jQuery statement then sets about its work, and the process
    > loops until you run out of memory.


    An interesting hypothesis, however a test in Safari and Firefox shows
    that while a deep clone of an element that contains a script element
    also clones the script, it isn't executed. e.g.

    <ul>
    <li>
    <script>console.log('hey');</script>
    </ul>
    <script>
    var el = document.getElementsByTagName('ul')[0].cloneNode(true);
    document.body.appendChild(el);
    </script>

    only prints one "hey" in the console.

    Similarly, placing a script element inside an element that clones the
    containing element doesn't cause an endless loop of clones, e.g.

    <ul>
    <li>item
    <script>console.log('hey');</script>
    <script>
    var el = document.getElementsByTagName('ul')[0].cloneNode(true);
    document.body.appendChild(el);
    </script>
    </ul>

    Leaving off the closing UL tag doesn't make any difference. In fact,
    if an LI is added after the script element, it's not included in the
    clone. So it would appear that the UL and its child nodes up to the
    script are cloned, then appended after the the browser has performed
    its error correction to close the UL.

    I haven't tested the OPs claims regarding jQuery's behaviour.


    --
    Rob
     
    RobG, Dec 4, 2011
    #4
  5. kiran

    Arno Welzel Guest

    kiran, 2011-12-04 06:02:

    > This is code which crashes browsers,below code do not have end UL tag.Though having end UL fixes the crash,but wanted to get this confirmed.
    >
    > <!DOCTYPE HTML>
    > <html>
    > <head>
    > <meta charset="utf-8">
    > <title>Simple Test Case</title>
    > </head>
    >
    > <body>
    > <ul>
    > <li>Test1</li>
    > <li>Test2</li>
    > <li>Test3</li>
    > <li>Test4</li>
    > <li>Test5</li>
    > <li>Test6</li>
    >
    >
    > <script type="text/javascript" src="js/jquery-1.6.4.js"></script>
    > <script>
    > jQuery('ul').clone().appendTo('body');
    > </script>
    > </body>
    > </html>


    Confirmed.

    I assume the problem is caused by the missing end tag for the list,
    since list is then not closed yet.

    clone() will collect existing elements. appendTo() will then append
    thoes elements. I did not have a look to the code of jquery, but i
    assume clone() will also see those elements which get created by appendTo().

    So this it what happens:

    - clone() will fetch "Test1"
    - appendTo() will create a copy of "Test1" and the end of the list
    - clone() will fetch "Test2"
    - appendTo() will create a copy of "Test2" and the end of the list
    ....
    - clone() will fetch "Test6"
    - appendTo() will create a copy of "Test6" and the end of the list

    and NOW clone() will see the first copy of "Test1" since the list is not
    closed by </ul> - therefore the whole process continues until the
    browser crashes. Well - at least my FF 8.0.1 asks me after a while if i
    want to stop the script ;-)



    --
    Arno Welzel
    http://arnowelzel.de
    http://de-rec-fahrrad.de
     
    Arno Welzel, Dec 4, 2011
    #5
  6. kiran

    RobG Guest

    On Dec 5, 12:04 am, Arno Welzel <> wrote:
    > kiran, 2011-12-04 06:02:
    >
    > > This is code which crashes browsers,below code do not have end UL tag.Though having end UL fixes the crash,but wanted to get this confirmed.

    >
    > > <!DOCTYPE HTML>
    > > <html>
    > > <head>
    > > <meta charset="utf-8">
    > > <title>Simple Test Case</title>
    > > </head>

    >
    > > <body>
    > > <ul>
    > > <li>Test1</li>
    > > <li>Test2</li>
    > > <li>Test3</li>
    > > <li>Test4</li>
    > > <li>Test5</li>
    > > <li>Test6</li>

    >
    > > <script type="text/javascript" src="js/jquery-1.6.4.js"></script>
    > > <script>
    > > jQuery('ul').clone().appendTo('body');
    > > </script>
    > > </body>
    > > </html>

    >
    > Confirmed.
    >
    > I assume the problem is caused by the missing end tag for the list,
    > since list is then not closed yet.


    Nothing to do with the missing closing tag, the browser deals with
    that. Adding a closing tag doesn't fix the issue. Moving the script
    element out of the UL does.


    > clone() will collect existing elements.


    The expression jQuery('ul') does that, clone calls clone the clone
    method of a jQuery object, which then calls .map which calls
    jQuery.clone() which finally gets around to calling clonNode(true) -
    and then does lost of weirdness, probably trying to fix "edge cases".


    > appendTo() will then append
    > thoes elements. I did not have a look to the code of jquery, but i
    > assume clone() will also see those elements which get created by appendTo().


    There is certainly some weirdness going on. If you look at the code,
    jQuery always creates a deep clone, then tries to fix attached events
    (since those added with attachEvent are cloned but those added with
    addEventListener aren't) and tries to fix obscure differences with
    attributes on some elements.

    In amongst all that, it gets lost. A jQuery object calls this
    function:

    clone: function( dataAndEvents, deepDataAndEvents ) {
    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
    deepDataAndEvents = deepDataAndEvents == null ?
    dataAndEvents : deepDataAndEvents;

    return this.map( function () {
    return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
    });
    },

    which calls map and passes it jQuery.clone as the "callback"

    map: function( callback ) {
    return this.pushStack( jQuery.map(this, function( elem, i ) {
    return callback.call( elem, i, elem );
    }));
    },

    and jQuery.clone is:

    jQuery.extend({
    clone: function( elem, dataAndEvents, deepDataAndEvents ) {
    var clone = elem.cloneNode(true),
    srcElements,
    destElements,
    i;

    if ( (!jQuery.support.noCloneEvent || !
    jQuery.support.noCloneChecked) &&
    (elem.nodeType === 1 || elem.nodeType === 11) &&
    !jQuery.isXMLDoc(elem) ) {
    // IE copies events bound via attachEvent when using cloneNode.
    // Calling detachEvent on the clone will also remove the events
    // from the original. In order to get around this, we use some
    // proprietary methods to clear the events. Thanks to MooTools
    // guys for this hotness.

    cloneFixAttributes( elem, clone );

    // Using Sizzle here is crazy slow, so we use
    getElementsByTagName
    // instead
    srcElements = getAll( elem );
    destElements = getAll( clone );

    // Weird iteration because IE will replace the length property
    // with an element if you are cloning the body and one of the
    // elements on the page has a name or id of "length"
    for ( i = 0; srcElements; ++i ) {
    // Ensure that the destination node is not null; Fixes #9587
    if ( destElements ) {
    cloneFixAttributes( srcElements, destElements );
    }
    }
    }

    // Copy the events from the original to the clone
    if ( dataAndEvents ) {
    cloneCopyEvent( elem, clone );

    if ( deepDataAndEvents ) {
    srcElements = getAll( elem );
    destElements = getAll( clone );

    for ( i = 0; srcElements; ++i ) {
    cloneCopyEvent( srcElements, destElements );
    }
    }
    }

    srcElements = destElements = null;

    // Return the cloned set
    return clone;
    },

    In true jQuery style, it disappears up its own arse in convoluted
    calls to all sorts of functions to "fix" things along the way. Someone
    might care to trawl through all that to find the issue but I'm not
    bothered.


    > So this it what happens:


    No point guessing, it has nothing to do with the missing closing tag.
    It is certainly something to do with the script element being within
    the element being cloned, but why is for someone else to discover.

    Care to log it as a bug? :)


    --
    Rob
     
    RobG, Dec 5, 2011
    #6
  7. kiran

    kiran Guest

    Thanks Rob and everyone for confirming this.I will bring this to the notice of jQuery team and see what they have to say on this.
     
    kiran, Dec 5, 2011
    #7
  8. kiran

    RobG Guest

    RobG, Dec 6, 2011
    #8
  9. kiran

    Scott Sauyet Guest

    RobG wrote:
    > On Dec 6, 1:06 am, kiran <> wrote:
    >
    >> Thanks Rob and everyone for confirming this.I will bring this to the notice of jQuery team and see what they have to say on this.

    >
    > Some thoughts from jQuery-o-philes:
    >
    > <URL:http://stackoverflow.com/questions/8379867/jquery-clone-causes-browse...


    Doctor, it hurts when I do this...

    :)
     
    Scott Sauyet, Dec 6, 2011
    #9
  10. kiran

    kiran Guest

    kiran, Dec 7, 2011
    #10
  11. kiran

    Evertjan. Guest

    kiran wrote on 07 dec 2011 in comp.lang.javascript:

    > They feel its code issue and not an issue with jQuery.
    >


    So jQuery is not just code?

    That it is code-to-be-avoided-at-all-cost is clear to me.

    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
     
    Evertjan., Dec 7, 2011
    #11
  12. kiran

    RobG Guest

    On Dec 6, 11:04 pm, Scott Sauyet <> wrote:
    > RobG wrote:
    > > On Dec 6, 1:06 am, kiran <> wrote:

    >
    > >> Thanks Rob and everyone for confirming this.I will bring this to the notice of jQuery team and see what they have to say on this.

    >
    > > Some thoughts from jQuery-o-philes:

    >
    > > <URL:http://stackoverflow.com/questions/8379867/jquery-clone-causes-browse...

    >
    > Doctor, it hurts when I do this...


    When "this" is something that should not hurt, it seems reasonable to
    bring it to the attention of someone who might be able to explain why
    does it hurt, if not fix it.

    Can you explain why browsers do not execute script elements in cloned
    nodes when using the DOM cloneNode method, but when using jQuery's
    clone function, they do?


    --
    Rob
     
    RobG, Dec 7, 2011
    #12
  13. kiran

    Scott Sauyet Guest

    RobG wrote:
    > On Dec 6, 11:04 pm, Scott Sauyet <> wrote:
    >> RobG wrote:
    >>> Some thoughts from jQuery-o-philes:
    >>> <URL:http://stackoverflow.com/questions/8379867/jquery-clone-causes-browse...

    >
    >> Doctor, it hurts when I do this...

    >
    > When "this" is something that should not hurt, it seems reasonable to
    > bring it to the attention of someone who might be able to explain why
    > does it hurt, if not fix it.


    Sorry, I should have put quotes around that. It was my attempt to
    summarize the responses from the jQuery community, not my own view.


    > Can you explain why browsers do not execute script elements in cloned
    > nodes when using the DOM cloneNode method, but when using jQuery's
    > clone function, they do?


    Yes.

    But I'm not sure I want to, because it might make it sound as though I
    agree with jQuery's decision on this. So, with the caveat in mind
    that I don't agree with their decision, let me first point out that
    jQuery is just Javascript. The DOM `cloneNode` method is still
    available. So they have to decide whether their method is just a thin
    wrapper around `cloneNode` or whether it is meant to do something
    different. They have chosen to do more. For one thing, jQuery copies
    over not just the DOM material, but also, optionally, copies the event
    handlers on the node and, with another option, on its descendents. I
    like this decision they made, but it could also lead to another
    question about "Why does this jQuery example differ from this parallel
    DOM one?"

    They also decided to run the scripts that were included in the copy
    (presumably only after the copy is attached to the DOM, although I
    haven't looked closely.) This allows for the style of dynamic
    generation that puts SCRIPT markup immediately after the markup for
    elements on which it will operate, something like:

    <div id="template">
    <div class="xyz">...</div>
    <script>process($(".xzy:last")[0]);</script>
    </div>

    $("#template").clone(true).appendTo(someContainer);

    With this, whatever server-side decisions that were made about how to
    handle this templated content are duplicated when it's cloned.

    This is not a style of development I like, and I don't really see a
    reason for jQuery to cater to what I see as poor practice, but I do
    understand it, and I've been on projects that used it heavily.

    So I suppose I've only answered half the question. This is why jQuery
    does run the scripts when cloning. As to why browsers don't do so in
    cloneNode, I can't really say.


    I also would like to point out that this code:

    <div>div
    <script>
    var el = document.getElementsByTagName('div')[0];
    document.body.appendChild(el.cloneNode(true));
    </script>
    </div>

    is not the most direct port of the jQuery code:

    <div>
    <script>$('div').clone().appendTo('body');</script>
    </div>


    This naive port would be semantically a little closer:

    <div>div
    <script>
    var els = document.getElementsByTagName('div');
    for (var i = 0; i < els.length; i++) {
    document.body.appendChild(els.cloneNode(true));
    }
    </script>
    </div>

    Of course because of the live NodeList, that one also has an infinite
    loop problem. It's a different issue than in the jQuery code, but
    it's still a real issue.

    -- Scott
     
    Scott Sauyet, Dec 7, 2011
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ronald
    Replies:
    3
    Views:
    3,606
    Jerom
    Oct 23, 2006
  2. F. GEIGER
    Replies:
    1
    Views:
    381
    F. GEIGER
    Apr 13, 2004
  3. joshc
    Replies:
    14
    Views:
    787
    Keith Thompson
    Jan 14, 2005
  4. Jeff
    Replies:
    5
    Views:
    511
  5. Replies:
    14
    Views:
    503
    James Kanze
    Dec 7, 2009
Loading...

Share This Page