3

对于给定的标签,我需要用很多元素包装它。这样用户就可以把

<img src="img.gif" >

但结果是

<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>

所以我决定把它做成jQuery插件。这是其中的一部分

(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);

起初我用我将使用的 div 来制作变量。但是这次我很难把它全部放在一起。我留下了 2 行不想与链接一起工作的行。起初我用裁剪包装图像,然后在裁剪 div 之后添加悬停 div。但是......第二行不起作用。我尝试了很多方法。到目前为止没有运气。似乎不可能添加用“包装”添加的东西。也许我做错了,所以也许你们中的某个人可以帮忙?:)

谢谢。

4

3 回答 3

2

对未插入页面的元素进行 DOM 操作可能有点棘手。

after,例如,只能对具有父元素的元素起作用。这是它的实现:

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

同样,wrap将调用before具有对称实现的方法。

有效的是通过使用append并从最外部的元素开始构建你的树:

cover.append(crop);
crop.append(image);
cover.append(hover);
于 2013-02-06T13:42:25.697 回答
1

您可以通过以下方式实现:

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

@dystroy 的答案并不完全正确:您可以在内存中的节点之后插入东西

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

你会发现所有 3 个节点都附加到 DOM

关键点是$.wrap。当你包装一些东西时,与其他操作不同,jQuery 会创建一个新副本,此时 dom 中的包装器与在内存中创建的引用不再相同。

以第一行为例:

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

最后但同样重要的是,实际上,我不喜欢这种方式来扩展 dom 节点。它使代码难以编写和维护。

这是我的解决方案:

(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 演示:http: //jsfiddle.net/vF4QH/1/

于 2013-02-06T14:07:05.730 回答
0

为什么不像这样一劳永逸地建立一个模板

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>';

然后,当您需要它时,您可以执行以下代码来插入图像标签

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

最后将其附加到 DOM 中的某个位置

//substitute body for where you wish to place the result
$("body").append(selection) 
于 2013-02-06T14:12:23.870 回答