JQuery收集一组元素,将每个元素展开,然后将所有元素包裹在新元素中

JQuery collect group of elements, unwrap each and then wrap all in new element

本文关键字:元素 然后 包裹 新元素 一组 JQuery      更新时间:2023-09-26

我正在尝试转换标记,其中每行都是<p>的企业列表,只有企业名称也包装在<strong>中。相反,我希望每个企业的整个清单都包装在一个<p>中,并使用<br/>来分隔行。下面是原始标记:

<div class="wrapper">
   <p><strong>Name of Business 1</strong></p>
   <p>Membership Level 1</p>
   <p>Name of Owner 1</p>
   <p>555 Someplace Ave 1</p>
   <p>Nowhere, OH 55555 1</p>
   <p>555-555-5555 1</p>
   <p><a href="mailto:test@test.com">test@test.com</a> 1</p>
   <p>Business Description 1</p>
   <p><strong>Name of Business 2</strong></p>
   <p>Membership Level 2</p>
   <p>Name of Owner 2</p>
   <p>555 Someplace Ave 2</p>
   <p>Nowhere, OH 55555 2</p>
   <p>555-555-5555 2</p>
   <p><a href="mailto:test@test.com">test@test.com</a> 2</p>
   <p>Business Description 2</p>
</div>

下面是我需要修改的内容:

<div class="wrapper">
    <p>
        <strong>Name of Business 1</strong><br>
        Membership Level 1<br>
        Name of Owner 1<br>
        555 Someplace Ave 1<br>
        Nowhere, OH 43021 1<br>
        555-555-5555 1<br>
        <a href="mailto:test@test.com">test@test.com</a> 1<br>
        Business Description 1<br>
    </p>
    <p>
        <strong>Name of Business 2</strong><br>
        Membership Level 2<br>
        Name of Owner 2<br>
        555 Someplace Ave 2<br>
        Nowhere, OH 43021 2<br>
        555-555-5555 2<br>
        <a href="mailto:test@test.com">test@test.com</a> 2<br>
        Business Description 2<br>
    </p>
</div>

我设法用一些最丑陋、最复杂的代码完成了它。基本上,我采取了一步一步的方法,因为我无法得到任何链式解决方案。

这是一个不幸的解决方案:

	jQuery('p > strong').parent('p').addClass('strong').has('br').addClass('clean');
	jQuery('p:not(.clean)').addClass('unwrap');
	
	jQuery('.unwrap.strong').nextUntil('.strong').each( function(){
		var theHTML = jQuery(this).html();
		jQuery(this).replaceWith('<span class="tomove">' + theHTML + '<br/></span>');
	});
	
	jQuery('span.tomove').each(function(){
		jQuery(this).appendTo( jQuery(this).prev('p.strong') );
	});
	
	jQuery('.unwrap strong').each(function(){
		var theHTML = jQuery(this).html();
		jQuery(this).replaceWith('<strong>' + theHTML + '</strong><br/>');
	});
	
	jQuery('span.tomove').replaceWith(function(){
		return jQuery(this).contents();
	});
	
	jQuery('p.strong.unwrap').addClass('clean').removeClass('unwrap');
p {background:yellow}
strong {background:red;color:white;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
	<p><strong>Name of Business 1</strong></p>
	<p>Membership Level 1</p>
	<p>Name of Owner 1</p>
	<p>555 Someplace Ave 1</p>
	<p>Nowhere, OH 55555 1</p>
	<p>555-555-5555 1</p>
	<p><a href="mailto:test@test.com">test@test.com</a> 1</p>
	<p>Business Description 1</p>
	<p><strong>Name of Business 2</strong></p>
	<p>Membership Level 2</p>
	<p>Name of Owner 2</p>
	<p>555 Someplace Ave 2</p>
	<p>Nowhere, OH 55555 2</p>
	<p>555-555-5555 2</p>
	<p><a href="mailto:test@test.com">test@test.com</a> 2</p>
	<p>Business Description 2</p>
</div>

我想有一种方法可以在一个链式命令中处理这个问题,但是我一直在尝试使用.nextUntil()和/或.add()构建引用,同时试图打开每个<p>并在包装每个组之前在该链中添加<br/>

有谁能提供更好的解决方案吗?

我是这么想的;无论业务的数量和数据参数的长度如何,它都应该工作。它确实要求第一个"p"元素包含一个"强"元素,并且除了企业名称之外,其他数据字段都没有强元素:

$(document).ready(function(){   
 var businesses = [], bizIndex = -1;
 $('.wrapper > p').each(function(i){
     var html = $(this).html();
     if ($(this).find('strong').length) {
       bizIndex++;
       businesses.push([html]);
     }
     else {
         businesses[bizIndex].push(html);
     }
 });
 $('.wrapper').empty();
 $.each(businesses, function(i) {
     var business = businesses[i];
   $('.wrapper').append($('<p>').html(business.join('<br>')+'<br>'));
 });
});
https://jsfiddle.net/2rz7jp4z/3/

下面使用Strong元素作为分隔符。提供的JSbin将它们添加到一个新的div中,以显示before/after。

http://jsbin.com/soyelozemi/4/edit

jQuery(document).ready(function(){
  var insert = $('<div class="wrapper2"></div>');
  var tempHolder = $('<p></p>');
  jQuery('.wrapper p').each(function(index){
    jQuery(tempHolder).append($(this).html() + '<br/>');
    if(jQuery(this).next().find('strong').length || index == jQuery('.wrapper p').length-1){
      jQuery(insert).append(tempHolder);
      tempHolder = jQuery('<p></p>');
    }
  });
  jQuery('.after').append(jQuery(insert));
});