在jQuery中更改此DOM结构的有效方法

时间:2012-03-27 08:41:06

标签: javascript jquery optimization

我想改革某个元素的结构。目前,它大致类似于这种结构。

<li>
    <a class="unitWrapper" href="location_url">
        stray textNode
        <img src="project1.jpg">
    </a>
    <a class="unitWrapper" href="another_url">
        link text
    </a>    
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>                     
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
</li>

我希望它使用jQuery构建到以下结构中,总结如下:

  • 获取列表项
  • 中找到的第一个链接
  • 从它的内容中打开它
  • 用它来包装列表项中的所有内容
  • 如果链接解包包含文本,请将其包装在<p>

这是新结构:

<li>
    <a href="location_url">
        <p>stray textNode</p>
        <img src="project1.jpg">
        <a class="unitWrapper" href="another_url">
            link text
        </a>    
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>                     
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </a>
</li>

我现在拥有的jQuery代码(有点笨重)就是:

$('li').find('.unitWrapper').eq(0).each(function() { //get only the first link
    var $link = $(this);

    var $wrapperLink = $('<a/>');                   //the wrapper link
    var $strayWrapper = $('<p/>');                  //wrapper for stray textNodes like "link text" above

    $wrapperLink.attr('href', $link.attr('href'));  //copy link's location to the wrapper

    $link.contents()                     //get all the link's contents
        .unwrap()                        //unwrap it
        .parent()                        //go to the parent (<li>)
        .contents()                      //get all li's contents
        .wrapAll($wrapperLink)           //wrap it with the <a> created earlier 
        .filter(function(){                         
            return this.nodeType == 3;   //get all stray text nodes
        })
        .wrapAll($strayWrapper);         //wrap them with the <p> created earlier
});​

有更好的方法吗?我唯一的方位是<li>和选择器字符串.unitWrapper

1 个答案:

答案 0 :(得分:1)

最简单的方法似乎是将其余内容附加到第一个元素:

$('li').each(function() {
    var first = $('a.unitWrapper', this).first();
    first.removeClass('unitWrapper')
         .append(first.siblings())
         .contents()
         .filter(function(){                         
             return this.nodeType == 3;   //get all stray text nodes
         })        
         .wrapAll("<p/>");
});

http://jsfiddle.net/infernalbadger/wA3EJ/3/

找不到比这个

更容易包装杂散文本节点的方法