在jQuery中更改此DOM结构的有效方法 [英] An efficient way to change this DOM structure in jQuery

查看:60
本文介绍了在jQuery中更改此DOM结构的有效方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<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

解决方案

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

$('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/

无法找到一种比这种方法更容易包装杂散文本节点的方法

i want to reform the structure of a certain element. currently, it roughly resembles this structure.

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

and i want it to be built into the following structure using jQuery which in summary:

  • gets the first link found in the list item
  • unwrap it from it's contents
  • use it to wrap everything in the list item
  • if the link unwrapped contained text, wrap them in <p>

here's the new structure:

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

and the jQuery code that i have now (which is kinda clunky) is this:

$('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
});​

is there a better approach to doing this? and the only bearings i have is the <li> and the selector string .unitWrapper

解决方案

Easiest way seems to be to append the rest of the content to the first a element:

$('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/

Cant find a way to wrap the stray text nodes easier than this

这篇关于在jQuery中更改此DOM结构的有效方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆