2

我目前有一组 div,它们位于 jQuery 嵌套可折叠集中,如果要让它们工作,需要一些时间。我已经让这些工作了,但是现在想要添加在单击我放置的向上箭头时根据请求在页面上向上移动列出的项目的功能。我编写了可以(在某种程度上)移动 div 的 javascript,如下所示:

$(document).ready(function() {
    $('.upItem').click(function(event) {
            if($(this.parentNode.parentNode).index() === 0) {
                alert($(this.parentNode.parentNode).attr('name') + ' is currently at the top');
            } else {
                $(this.parentNode.parentNode).insertBefore(this.parentNode.parentNode.previousSibling);
                alert($(this.parentNode.parentNode).attr('name') + ' moved Up');
            }
        }
    );
});

父节点块是为了让正确的元素移动,它们最终看起来移动得很好。

我正在使用 PHP 生成的类似于以下内容的 HTML:

<div name="H4Order_1" class="h4Holder">
<h4 id="L2_item_29" class="collapsible collapse-open"><span></span>SuperBowl</h4>
<div class="container2" style="display: block;">
    <div name="H5Order_1" class="h5Holder">
        <span class="buttonHolder">
            <span class="upItem">▲&lt;/span>
        </span>
        <h5>Item 1</h5>
    </div>
    <div name="H5Order_2" class="h5Holder">
        <span class="buttonHolder">
            <span class="upItem">▲&lt;/span>
        </span>
        <h5>Item 2</h5>
    </div>
    <div name="H5Order_3" class="h5Holder">
        <span class="buttonHolder">
            <span class="upItem">▲&lt;/span>
        </span>
        <h5>Item 3</h5>
    </div>
    <div name="H5Order_4" class="h5Holder">
        <span class="buttonHolder">
            <span class="upItem">▲&lt;/span>
        </span>
        <h5>Item 4</h5>
    </div>
</div>

我遇到的问题是,当我单击具有 .upItem 类的元素时,脚本会触发,并且当项目位于顶部以及“移动”时,我可以看到警报,但通常元素确实实际不动。我会看到它已被移动的警报,但它没有按预期向上移动。在下一次单击时,它将移动。有时在此处单击一下后,所有元素都会按预期开始移动,每次单击一次,但这只是在对多个项目进行大量单击之后才发生的。

有什么方法可以排除故障,以找出为什么有时需要单击 2 次才能使项目实际移动?

根据请求,这里是 jfiddle:

http://jsfiddle.net/jwnqh/

4

3 回答 3

2

您试图在之前插入节点,previousSiblingpreviousElementSibling这正是您想要的。这是因为两个父容器之间有一个文本节点。

当然,这个特定的属性是相对较新的,除非您有解决方法,否则它不适用于旧浏览器(IE < 9)。

这将是一种将项目向上移动到兄弟链的更直接的方法:

$('.upItem').click(function(event) {
  //var $parent = $(this).closest('.h5Holder');
  var $parent = $(this).parent().parent();

  if ($parent.index() === 0) {
    alert($parent.attr('name') + ' is currently at the top');
  } else {
    $parent.prev().before($parent);
    alert($parent.attr('name') + ' moved Up');
  }
});

演示

在这里,.prev().before()请确保您在前一个元素而不是前一个节点之前插入。

它还缓存了锚的父容器,使代码更容易理解。

于 2013-05-16T06:48:24.580 回答
1

尝试这个:-

演示

 $(document).ready(function() {
    $('.upItem').click(function(event) {
        var div = $(this).closest('div.h5Holder');
            if(div.index() === 0) {
                alert(div.attr('name') + ' is currently at the top');
                return;
            }
         div.insertBefore(div.prev());
        alert(div.attr('name') + ' moved Up');
        }
    );
});

$(this.parentNode.parentNode).insertBefore(this.parentNode.parentNode.previousSibling);是罪魁祸首,因为this.parentNode.parentNode.previousSibling它给出了一个文本节点(空白)而不是你正在寻找的实际元素。

于 2013-05-16T06:45:22.803 回答
0

您需要使用previousElementSibling跳过文本节点。

$(document).ready(function () {
    $('.upItem').click(function (event) {
        if ($(this.parentNode.parentNode).index() === 0) {
            alert($(this.parentNode.parentNode).attr('name') + ' is currently at the top');
        } else {
            $(this.parentNode.parentNode).insertBefore(this.parentNode.parentNode.previousElementSibling);
            alert($(this.parentNode.parentNode).attr('name') + ' moved Up');
        }
    });
});

小提琴

于 2013-05-16T06:54:01.383 回答