0

I have four div elements

    <div id="one" class="present" style="display: none;">1</div>
    <div id="two" class="present" style="display: none;">2</div>
    <div id="three" class="present" style="display: none;">3</div>
    <div id="four" class="present" style="display: none;">4</div>

At some point if it becomes

    <div id="one" class="present" style="display: none;">1</div>
    <div id="two" class="present" style="display: none;"></div>//this value gets deleted
    <div id="three" class="present" style="display: none;">3</div>
    <div id="four" class="present" style="display: none;">4</div>

I want it to get rearrange as

    <div id="one" class="present" style="display: none;">1</div>
    <div id="two" class="present" style="display: none;">3</div>//this moves up
    <div id="three" class="present" style="display: none;">4</div>//this moves up
    <div id="four" class="present" style="display: none;"></div>

Only these four elements have class "present" so I would think I could do something by iterating through it, but not sure how to get the result i am looking for

I tried:

    $(".present").each(function(){

    if ($(this).is(":empty"))
    {
        var target =  $(this);
        $(".present").each(function(){
             $(this).not(":empty");
             target.html($(this).html());
        });
    }
});

but this seem to put last div's html on the blank space, which is not what i want. I want them to push up.

ps: its not just one value that might get deleted. Any value in middle can get deleted. Even multiple values can get deleted, meaning, I could only have value in the last div, which i would ideally want to move to first div

4

5 回答 5

3

我在上一个代码中发现了一些问题。

我从您的原始问题中假设您不希望重新排列 div 元素,而只希望重新排列每个 div 的 html 内容。

假设你有这个:

<div id="one" class="present">1</div>
<div id="two" class="present"></div>
<div id="three" class="present">3</div>
<div id="four" class="present"></div>
<div id="five" class="present">5</div>
<div id="six" class="present"></div>
<div id="seven" class="present"></div>
<div id="eight" class="present">8</div>
<div id="nine" class="present"></div>
<div id="ten" class="present"></div>

可能有更短的方法,但这似乎有效。

$(".present").each(function () {
    var $this = $(this);

    if ($this.is(":empty")) {
        var $nextItem = $this.nextAll().not(':empty').first();

        console.log($nextItem.html());

        if($nextItem.length){
            $this.html($nextItem.html());
            $nextItem.empty();
        }
    }
});

生成的 HTML 是:

<div id="one" class="present">1</div>
<div id="two" class="present">3</div>
<div id="three" class="present">5</div>
<div id="four" class="present">8</div>
<div id="five" class="present"></div>
<div id="six" class="present"></div>
<div id="seven" class="present"></div>
<div id="eight" class="present"></div>
<div id="nine" class="present"></div>
<div id="ten" class="present"></div>

演示- 使用下一个非空值


正如您在生成的 HTML 中看到的那样,div 元素没有被重新排序,只是 HTML 内容被向上移动,填充了空白,因此将空白留在了底部。它也适用于中间和末尾缺少的多个空值。

于 2013-07-11T20:38:48.133 回答
2

很确定这可以解决问题:

$(".present").each(function(){
  if ($(this).is(":empty")){
    $(this).append($(this).parent());
  }
});

append 函数删除元素并将其附加到目标。通过将它附加到它已经在其中的容器中,它应该从 dom 中移除并在最后重新插入,这应该允许较低的对象自然地向上移动。

如果您想为效果设置动画,您可以克隆对象而不是追加,然后定位它的第一个实例,将高度值设置为 0,然后将其移除。


因此,为了在容器上维护正确的 ID,您可以将每个对象的标记替换为下一个对象的标记,但其中涉及到相当多的内容处理。我会建议这样的事情(您需要稍微更改您的 id 命名方案,以使其更容易设置。不确定这是否适合您的情况。)

var myObjects = $(".present");
$(myObjects).each(function(){
  if ($(this).is(":empty")){
    $(this).append($(this).parent());
  }
}).each(function(){
  $(this).attr('id', 'a' + ($(this).index() + 1) )
});

因此,您的 id 将是 a1、a2、a3 等……这封信是因为您不能以数字开头的 id 或类,但如果需要,可以用更具描述性的内容替换。

根据您使用这些 ID 的方式,您可以完全摆脱它们,并在使用这些 ID 的任何函数中直接检查对象的 index() 。

所以如果你正在做这样的事情:

$("#one").stuff();

..你可以改为使用:

$(".present:eq(0)").stuff();

当然,如果您在 css 中引用特定的 ID,这可能也不会起作用。

于 2013-07-11T20:31:38.597 回答
1

你不能简单地这样做:

$(".present:empty").each(function(index,item) {
    $(this).remove();
    $("#parent").append(this);
});

只需将它们拉出并将它们添加回列表的末尾即可。

这是一个小提琴来说明。

于 2013-07-11T20:35:50.567 回答
0

简单的解决方案...(或替代方案
现场演示

function check(id) {
    var ele = document.getElementById(id),
        parent = ele.parentNode,
        len = parent.children.length,
        child = null;

    for (var i = 0; i < len; i++) {
        child = parent.children[i];
        if (child.nodeType === 1 && child.innerHTML.length === 0) {
            parent.appendChild(child);
        }
    }
}
于 2013-07-11T20:38:00.167 回答
0

只需在最后一个非空的之后插入所有空的

$('.present:empty').insertAfter('.present:not(:empty):last');

http://jsfiddle.net/4QYjW/

编辑:

我没有注意到您只是在移动文本-您可以这样做

var withText = $('.present:not(:empty)').clone();// get all with text
$('.present').text(''); // clear all the text
// loop through and add the number text
$.each(withText, function(i,v){
    $('.present').eq(i).text($(v).text()); 
});

http://jsfiddle.net/k42Ny/

于 2013-07-11T20:39:18.040 回答