我有以下模型(这里是一个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>
基本上,如果jt-item-price在jt-detail中,我想附加到前面的jt-header;这是上面的第一个对联。如果它已经在jt-header内,请保持原样(第二个对联),以便上述内容成为:
<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>
我该怎么做?我会认为detach()。appendTo()但我如何检测到jt-item-price在一个细节内?我如何将它告诉前面的jt-header(可能有介入的非jt-header元素) ?
THX
一个更现实的例子似乎打破了使用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>
答案 0 :(得分:5)
Jquery append()接受一个函数,你可以使用以下逻辑:
$('.jt-header').append(function(){
return $(this).next('.jt-detail').children('.jt-item-price');
});
答案 1 :(得分:2)
考虑到你的编辑#1,你应该可以通过组合.closest()/ .prev()/ .find()
来实现。喜欢这个
$(function(){
$('#move').on('click',function(){
$('.jt-detail .jt-item-price').each(function(){
$this = $(this);
$this.appendTo($this.closest('.jt-row').prev().find('.jt-header'));
});
});
});
条件是保持当前html结构与你的jt-row:)
答案 2 :(得分:2)
实际上相当简单,只需要正确遍历DOM树
根据您的示例,这是逐步细分:
class="jt-item-price"
jt-detail
jt-header
jt-row
元素
jt-item-price
元素&amp;重复代码如下所示:
$('.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);
}
})
答案 3 :(得分:1)
您只需使用jQuery.parent()
和jQuery.prev()
方法进行元素定位。
在你的情况下这很简单,因为你的类已经被定义了,所以在这种情况下,下面的代码可以解决这个问题:
jQuery(document).ready(function(){
// Button required for testing purposes only
jQuery('.moveIt').on('click', movePrice);
// If script should run automatically
// move everything out of this function
function movePrice() {
// For maintaining purposes
var _price = 'jt-item-price';
var _from = 'jt-detail';
var _to = 'jt-header';
// Vudu stuff
jQuery('div.'+_price).each(function(){
// Get elements
var _this = jQuery(this);
var _parent = _this.parent();
var _parentClass = _parent.attr('class');
// If parent matches the wrapper we want
// to take the element out of
if( _parentClass == _from ) {
// Get its parent previous element
var _finalWrapper = _this.parent().prev();
// If previous element class matches our
// destination's class
if( _finalWrapper.attr('class') == _to ) {
// Put price there
jQuery(_finalWrapper).append( _this );
}
}
});
}
});
/**
* Answer to: http://stackoverflow.com/questions/28661854/how-to-move-an-element-into-if-it-is-contained-in-another-element
*/
jQuery(document).ready(function(){
// Testing with no Row wrappers
jQuery('.unwrap').on('click', function(){
jQuery('.row > .jt-header').unwrap();
});
// Button required for testing purposes only
jQuery('.moveIt').on('click', movePrice);
// If script should run automatically
// move everything out of this function
function movePrice() {
// For maintaining purposes
var _price = 'jt-item-price';
var _from = 'jt-detail';
var _to = 'jt-header';
// Vudu stuff
jQuery('div.'+_price).each(function(){
// Get elements
var _this = jQuery(this);
var _parent = _this.parent();
var _parentClass = _parent.attr('class');
// If parent matches the wrapper we want
// to take the element out of
if( _parentClass == _from ) {
// Get its parent previous element
var _finalWrapper = _this.parent().prev();
// If previous element class matches our
// destination's class
if( _finalWrapper.attr('class') == _to ) {
// Put price there
jQuery(_finalWrapper).append( _this );
}
}
});
}
});
.jt-header {
clear: both;
border: 1px solid #f5f5f5;
padding: 0px .5em;
margin: .5em;
background: #f1f1f1;
}
.jt-detail,
.jt-item-price {
display: inline-block;
}
.jt-detail { padding: 1em; }
.jt-item-price {
margin: 1em 0;
background: #f1f1f1;
padding: .5em;
font-weight: bold;
}
.row {
display: block;
padding: .5em;
border: 1px solid #efefef;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class='jt-header'>Product 1</div>
<div class='jt-detail'>Product Details
<div class='jt-item-price'>12.34</div>
</div>
</div>
<div class="row">
<div class='jt-header'>Product 2
<div class='jt-item-price'>34.45</div>
</div>
<div class='jt-detail'>Product Details</div>
</div>
<div class="row">
<div class='jt-header'>Product 3</div>
<div class='jt-detail'>Product Details
<div class='jt-item-price'>20.55</div>
</div>
</div>
<hr />
<button class="moveIt">Move Prices</button>
<button class="unwrap">Unwrap from Rows</button>
我希望这会有所帮助。
祝你好运, JoséSAYAGO。
答案 4 :(得分:1)
答案 5 :(得分:1)
这里是小提琴链接:http://jsfiddle.net/fjjeo22h/1/
代码:
$(".jt-detail .jt-item-price").each(function () {
var price = $(this);
var prevhead = $(this).parent(".jt-detail").prev(".jt-header");
if (!prevhead.find('.jt-item-price').length > 0) {
price.appendTo(prevhead);
}
});
答案 6 :(得分:1)
尝试
// filter `.jt-item-price` ,
// return elements not already children of `jt-header`
var itemPrice = $(".jt-item-price").not(function (i, el) {
return $(el).parent().is(".jt-header")
});
// `itemPrice` parent element
var item = itemPrice.parents(".jt-row");
// if `item` contains child element `jt-header` ,
// append `itemPrice` at current `item`
if (item.find(".jt-header").is("*")) {
item.find(".jt-header").append(itemPrice)
}
// else filter `.jt-row` by index 1 less than current `item`,
// append `itemPrice` to `.jt-header` at selected `.jt-row`
else {
item.siblings(".jt-row").eq(item.index(".jt-row") - 1)
.find(".jt-header").append(itemPrice)
};
// filter `.jt-item-price` ,
// return elements not already children of `jt-header`
var itemPrice = $(".jt-item-price").not(function (i, el) {
return $(el).parent().is(".jt-header")
});
// `itemPrice` parent element
var item = itemPrice.parents(".jt-row");
// if `item` contains child element `jt-header` ,
// append `itemPrice` at current `item`
if (item.find(".jt-header").is("*")) {
item.find(".jt-header").append(itemPrice)
}
// else filter `.jt-row` by index 1 less than current `item`,
// append `itemPrice` to `.jt-header` at selected `.jt-row`
else {
item.siblings(".jt-row").eq(item.index(".jt-row") - 1)
.find(".jt-header").append(itemPrice)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<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>
答案 7 :(得分:0)
使用此Demo Here
$(function(){
$('#move').on('click',function(){
$('.jt-detail .jt-item-price').each(function(){
$this = $(this);
$this.appendTo($this.closest('.jt-row').prev().find('.jt-header'));
});
});
});
答案 8 :(得分:0)
你可以使用nextUntil,它会迭代直到找到元素。有了这个,你可以在标题和细节之间拥有尽可能多的元素(这是我理解的目标吗?)
运行以下代码段。我只是将标题加粗,以便您可以看到它正常工作。
$('.jt-header').each(function () {
var $this = $(this)
$this.append(function () {
var el = $this.next('.jt-detail')
if (el.length < 1) el = $this.nextUntil('.jt-detail').next('.jt-detail');
return el.children('.jt-item-price');
});
});
.jt-header {
font-weight:bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<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>
<hr />
<div class="jt-header">a header 1</div>
<div class="something-between">La la la I'm in the way :P</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>