jQuery insertBefore()和parentNode看起来不稳定

jQuery insertBefore()和parentNode看起来不稳定,jquery,css,Jquery,Css,我目前有一组div,它们位于jQuery嵌套的可折叠集合中,如果要让它们正常工作,需要一点时间。我已经让这些工作,但现在想添加的能力,以转移在页面上列出的项目时,按要求点击向上箭头我已经放置。我已经编写了javascript,可以(某种程度上)移动div,如下所示: $(document).ready(function() { $('.upItem').click(function(event) { if($(this.parentNode.parentNode)

我目前有一组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>

橄榄球
▲
项目1
▲
项目2
▲
项目3
▲
项目4

我遇到的问题是,当我单击class.upItem中的元素时,脚本会触发,当项目位于顶部以及“移动”时,我可以看到警报,但通常元素不会实际移动。我将看到警报已被移动,但未按预期向上移动。下一次单击时,它将移动。有时,在点击这里和那里一点之后,所有元素都会像预期的那样开始移动,每次点击一次,但这只是在多次点击多个项目之后

是否有任何方法可以排除故障,找出为什么有时需要点击两下才能让am项目实际移动

每个请求都有jfiddle:

试试这个:-


您的
$(this.parentNode.parentNode).insertBefore(this.parentNode.parentNode.previousSibling)
是罪魁祸首,因为
this.parentNode.parentNode.previousSibling
提供了一个textnode(空格),而不是您要查找的实际元素。

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

当然,这个特殊属性相对较新,除非您有解决方法,否则它不适用于较旧的浏览器(即<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()
确保插入的是前一个元素,而不是前一个节点


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

您需要使用
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');
        }
    });
});

如果我们能看到这种情况,那就更好了。。你能做一把小提琴吗。。。使用浏览器中的DOM inspector和Javascript调试器对此进行故障排除。问题的原因是
。previousSibling
返回包含空格的文本节点。您需要使用
.previousElementSibling
,但答案中的jQuery代码更清晰。我将进行调整,看看是否适合我。。我很快会让你知道的。看起来这是可行的,但我必须调整,因为我需要考虑嵌套格式(即,我有H1、H2、H3、H4和H5,)。有没有一种方法可以让.closest()为所有级别使用公共类?或者我需要为每个级别创建一个函数。h1Holder、.h2Holder等?@Silvertiger如果容器元素总是由两个级别分隔,而不是
.closest()
,那么您可以只使用
.parent().parent()
当然:)@jack这不就是我对parentNode.parentNode所做的吗?还是不同?@Silvertiger与parentNode.parentNode完全相同
$(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');
        }
    });
});