jQuery insertBefore()和parentNode出现片状

时间:2013-05-16 06:39:14

标签: jquery css

我目前有一组div,它们位于jQuery嵌套的可折叠集中,如果要玩它们就可以使用它们。我已经让这些工作,但现在想要添加能够在点击我放置的向上箭头时按要求在页面上移动列出的项目。我编写的javascript有效(按类别)移动div,如下所示:

$(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">▲</span>
        </span>
        <h5>Item 1</h5>
    </div>
    <div name="H5Order_2" class="h5Holder">
        <span class="buttonHolder">
            <span class="upItem">▲</span>
        </span>
        <h5>Item 2</h5>
    </div>
    <div name="H5Order_3" class="h5Holder">
        <span class="buttonHolder">
            <span class="upItem">▲</span>
        </span>
        <h5>Item 3</h5>
    </div>
    <div name="H5Order_4" class="h5Holder">
        <span class="buttonHolder">
            <span class="upItem">▲</span>
        </span>
        <h5>Item 4</h5>
    </div>
</div>

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

有什么方法可以解决问题,找出为什么有时需要2次点击才能让物品实际移动?

此处的每个请求都是jfiddle:

http://jsfiddle.net/jwnqh/

3 个答案:

答案 0 :(得分:2)

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

当然,除非您有解决方法,否则此特定属性相对较新,不适用于较旧的浏览器(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');
  }
});

Demo

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

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

答案 1 :(得分:1)

试试这个: -

Demo

 $(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提供了一个textnode(空格),而不是您正在寻找的实际元素。

答案 2 :(得分: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');
        }
    });
});

FIDDLE