but the ...">

Jquery making html

for a given tag I need to wrap it with multiple elements. So that the user can put

<img src="img.gif" >

      

but the result will be

<div class="total">
    <div class="cover">
        <div class="crop">
            <img src="img.gif" alt> 
        </div>
        <div class="hover">
            <div class="peel">
                <div class="links">
                    <a href="#">FB</a>
                </div>

            </div>
        </div>
    </div>
</div>

      

So, I decided to do it in a jQuery plugin. And here's a piece of it

(function($) {
$.fn.peel = function(options) {
    var defaults = {};
    var settings = $.extend({},defaults, options);

    return this.each(function() {
        $(this).load(function() {
            var image = $(this);
            var total = $('<div />', {'class' : 'total'});
            var cover = $('<div />', {'class' : 'cover'});
            var crop = $('<div />', {'class': 'crop'});
            var hover = $('<div />', {'class' : 'hover'});
            var peel = $('<div />', {'class' : 'peel'});
            var links = $('<div />', {'class' : 'links'});
            var a = $('<a>', {'href' : '#', 'text' : 'FB'});
            //Chaining begins here
            image.wrap(crop);
            crop.after(hover);

        });
    });

};
})(jQuery);

      

First, I make variables with divs that I will be using. But this time it's hard for me to do it all together. I left 2 lines that don't want chaining. I first wrap the image with crop and then add the hover div after harvest. But ... 2nd line doesn't work. I've tried it many times. No luck yet. It looks like it is not possible to add something that is added with "wrap". Maybe I am wrong, maybe some of you could help? :)

Thank.

+3


source to share


3 answers


you can achieve it like this:

image.wrap(total).wrap(cover).wrap(crop)
    .closest('.crop')
    .after(a.wrap(hover).wrap(peel).wrap(links).closest('.hover'));

      

@ dystroy's answer is not entirely correct: you can insert the thing after the node into memory

cover.append(crop).append(hover).appendTo('body');

      

you will see all 3 nodes have been added to the DOM

key point $.wrap

. when you wrap something, not as another operation, jQuery will create a new copy, at which time the wrapper in the dom is no longer the one that was created in memory.



take the first line as an example:

var domCrop = image.wrap(total).wrap(cover).wrap(crop)
    .closest('.crop');
console.log(domCrop.is(crop)); //false, domCrop and the corp in mem not point to the same ref

      

Last but not least , I actually don't like this way of extending the dom node. it made the code difficult to write and maintain.

here's my solution:

(function($) {
$.fn.peel = function(options) {
    var defaults = {};
    var settings = $.extend({},defaults, options);
    var html = '<div class="total">'
        + ' <div class="cover">'
        + '   <div class="crop"></div>'
        + '   <div class="hover">'
        + '      <div class="peel">'
        + '         <div class="links">'
        + '            <a href="#">FB</a>'
        + '         </div>'
        + '      </div>'
        + '   </div>'
        + ' </div>'
        + '</div>';

    return this.each(function() {
        $(this).load(function() {
            var $image = $(this);

            //introduced a placeholder. 
            //not to replace the $image directly, just for keeping all the event handler bound to $image.
            var $placeholder = $('<span/>').insertAfter($image);
            $(html).find('.crop').append($image)
                .end()
                .replaceAll($placeholder);
        });
    });

};
})(jQuery);

      

jsFiddle Demo: http://jsfiddle.net/vF4QH/1/

+1


source


DOM layouts on elements not inserted into the page can be a little tricky.

after

, for example, can only work with a parent element. Here is its implementation:

after: function() {
    return this.domManip( arguments, false, function( elem ) {
        if ( this.parentNode ) {
            this.parentNode.insertBefore( elem, this.nextSibling );
        }
    });
},  

      



Likewise, wrap

will call before

that has a symmetric implementation.

Which works to build your tree using append

and starting from the outermost element:

cover.append(crop);
crop.append(image);
cover.append(hover);

      

+2


source


Why not just build a tempalte once and for all like this one

var htmlTemplate = '<div class="total">'
    htmlTemplate += ' <div class="cover">';
    htmlTemplate += '   <div class="crop"></div>';
    htmlTemplate += '   <div class="hover">';
    htmlTemplate += '      <div class="peel">';
    htmlTemplate += '         <div class="links">';
    htmlTemplate += '            <a href="#">FB</a>';
    htmlTemplate += '         </div>';
    htmlTemplate += '      </div>';
    htmlTemplate += '   </div>';
    htmlTemplate += ' </div>';
    htmlTemplate += '</div>';

      

Then when you need it you can do something like the below code to insert an image tag

var selection = $(htmlTemplate);
selection.find('.crop').html('<img src="img.gif" alt>');

      

and finally add it somewhere in the DOM

//substitute body for where you wish to place the result
$("body").append(selection) 

      

0


source







All Articles