Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: unwrap element in HTML string

http://jsfiddle.net/vol7ron/vZLnr/

I'm trying to find the best way to unwrap an HTML string (like AJAX response), without first attaching it to the document. Also, which is the best for memory management?

HTML

  • <div class="label">Start With:</div>
    <pre id="original"></pre>
    
    <div class="label">What's Wanted:</div>
    <pre id="wanted"><div>foo</div><div>bar</div></pre>
    
    <hr />
    
    <div class="label">Attempt: .find()</div>
    <pre id="find"></pre>
    
    <div class="label">Attempt: .closest()</div>
    <pre id="closest"></pre>
    

CSS

  • .label    { font       : italic bold 11px Georgia;   margin    : 1em 0 .5em; }
    pre       { border     : 1px solid black;            padding   : 1em;        }
    hr        { margin     : 1.5em 0 1em; }
    
    #original { background : #eee; }
    #wanted   { background : #def; }
    

JavaScript

  •    var $html= "<pre><div>foo</div></pre><pre><div>bar</div></pre>";
    
       // No Changes
       jQuery('#original').html($html);
    
    
       // Find
       var $find = jQuery($html).find('*').unwrap();
       jQuery('#find').html($find);
    
    
       // Closest
       var $closest = jQuery($html).closest('pre').unwrap().html();
       jQuery('#closest').html($closest);
    
    
       // Wrapped
       var $pre = jQuery('pre', jQuery($html).wrap('<div />').parent() );
       $pre.each(function(){
                    jQuery('#wrapped').append(jQuery(this).html());
                });
    
       //=========== Prettify Output ===========
       var $wanted = jQuery('#wanted').html();
       jQuery('pre').not('#wanted, #original, #original *')
                    .each(function(){
                      var t = jQuery(this);
                      t.css({background: t.html()==$wanted?'#efe':'#fee'});
                    });
    

Edit

  1. The .find() method needs some work as it removes the white space containers. Imagine <pre><span>Code</span> <span>Here</span></pre>, which would turn into <span>Code</span><span>Here</span> (dropped whitespace).
like image 692
vol7ron Avatar asked Nov 05 '22 16:11

vol7ron


1 Answers

One generalizable way to unwrap it would be to simply traverse the string, either for the outermost tag or for a specific tag, adding each character that isn't part of the tag to a new string (once you hit a <, check the whole tag). Once it's found, start a counter at 0 and continue traversing the string until its closing tag is found, adding each character to the new string. If at this point the counter is 0, skip the tag and add the rest of the original string to the new string. Any time you encounter an opening tag of any kind, add one to the counter. Any closing tags, subtract 1 (so you dont end up removing the closing tag from a nested tag).

I can't really speak to memory management, as I am unfamiliar with how javascript manages memory.

I hope I have been of some help.

like image 93
yoozer8 Avatar answered Nov 09 '22 12:11

yoozer8