how to move an element into if it is contained in another element

I have the following mockup (here's a jsbin: http://jsbin.com/vadutezaci/1/edit?html,css,output):

<div class='jt-header'>a header 1</div>
<div class='jt-detail'>a detail 1
  <div class='jt-item-price'>12.34</div>
</div>
<div class='jt-header'>another header 2<div class='jt-item-price'>34.45</div></div>
<div class='jt-detail'>another detail 2
</div>

Basically, if a jt-item-price is within a jt-detail, I'd like to append to the preceding jt-header; this is the first couplet above. If it is within a jt-header already, leave as is (the second couplet) so that the above becomes:

<div class='jt-header'>a header  <div class='jt-item-price'>12.34</div>
</div>
<div class='jt-detail'>a detail
</div>
<div class='jt-header'>another header<div class='jt-item-price'>34.45</div></div>
<div class='jt-detail'>another detail
</div>

How would I do this? I would think detach().appendTo() but how would I detect that the jt-item-price is within a detail and how would I tell it to the preceding jt-header (there might be intervening non-jt-header elements)?

thx

edit #1

a more realistic example which seems to break using next():

<div class='jt-row'>
<div class='jt-header'>a header 1</div>
</div>
<div class='jt-row'>
<div class='jt-detail'>a detail 1
  <div class='jt-item-price'>12.34</div>
</div>
</div>
<div class='jt-row'>

<div class='jt-header'>another header 2<div class='jt-item-price'>34.45</div></div>
</div>
<div class='jt-row'>
<div class='jt-detail'>another detail 2
</div>
</div>

Jquery append() accepts a function, you can use following logic:

$('.jt-header').append(function(){
    return $(this).next('.jt-detail').children('.jt-item-price');
});

-jsFiddle-


Considering your edit #1, you should be able to do it by combining .closest() / .prev() / .find()

Like this

$(function(){
    $('#move').on('click',function(){
        $('.jt-detail .jt-item-price').each(function(){
            $this = $(this);
            $this.appendTo($this.closest('.jt-row').prev().find('.jt-header'));
        }); 
    });
});

Check the fiddle here

The condition is to keep the current html structure with your jt-row :)


Fairly simple actually, just have to properly traverse the DOM tree

Per your example here is the step by step breakdown:

  • FOR EACH element with the class="jt-item-price"
  • IF the parent class is equal to jt-detail
  • THEN append the element to the preceding jt-header element present in jt-row
  • ELSE Move to the next jt-item-price element & repeat
  • Here is what the code looks like:

    $('.jt-item-price').each(function(){
      if($(this).parent().hasClass('jt-detail')){
        var $headerCheck = $(this).parents('.jt-row');
        var loopCheck = false;
    
        while(!loopCheck){
          $headerCheck = $headerCheck.prev();
          if($headerCheck.find('.jt-header').length > 0){
            loopCheck = true;
          }
        }
    
        $(this).appendTo($headerCheck);
      }
    })
    

    ~Live CodePen~

    链接地址: http://www.djcxy.com/p/42556.html

    上一篇: 在C#中使用C ++ Protobuf实现

    下一篇: 如果元素被包含在另一个元素中,如何移动元素