如何在JavaScript中交换HTML元素?

时间:2010-05-31 11:15:42

标签: javascript dom

我使用经典的Javascript进行DOM脚本编写,我在容器DIV中有一组DIV。 在孩子DIV的点击事件中,我想要使事件与其上方的DIV交换的孩子DIV。 我的代码在这里..

 <div id="container">
        <div onclick="swapDiv(event);">1</div>
        <div onclick="swapDiv(event);">2</div>
        <div onclick="swapDiv(event);">3</div>
 </div>

如果单击DIV 2,则应与DIV 1交换

6 个答案:

答案 0 :(得分:15)

元素的parentNode属性为您提供父节点。元素具有insertBefore函数,该元素在另一个引用元素之前插入元素(如果它已经在树中的其他位置,则移动它)。并且节点有previousSibling,它为您提供上一个兄弟节点(可能是也可能不是元素)。所以:

function swapDiv(elm) {
    var previous = findPrevious(elm);
    if (previous) {
        elm.parentNode.insertBefore(elm, previous);
    }
}

... findPrevious看起来像这样:

function findPrevious(elm) {
   do {
       elm = elm.previousSibling;
   } while (elm && elm.nodeType != 1);
   return elm;
}

...您的onclick属性应该是:

onclick="swapDiv(this);"

...虽然您可能希望在IE上调查DOM2事件(addEventListenerattachEvent)。

稍微过了一点,但我是否可以推荐使用可以让您的生活更轻松的几个库中的任何一个,例如PrototypejQueryClosureany of several others。实际上,早期版本中存在错误,因为自从我直接处理DOM以来它已经 。 : - )

答案 1 :(得分:13)

此代码将执行您想要的操作(如果要将选定内容与第一个子元素交换)。如果你想要别的东西,你需要更精确。

<script type="text/javascript">

function swapDiv(event,elem){
    elem.parentNode.insertBefore(elem,elem.parentNode.firstChild);
}

</script>


 <div id="container">
        <div onclick="swapDiv(event,this);">1</div>
        <div onclick="swapDiv(event,this);">2</div>
        <div onclick="swapDiv(event,this);">3</div>
 </div>

答案 2 :(得分:2)

从它的声音中你基本上只想将div与之前的div交换,与previousSibling一起使用。您可以查看执行insertBefore但不使用现有元素创建新元素。我不确定附加事件会发生什么,如果它们将被正确复制。

答案 3 :(得分:2)

原则上你只需insertBefore你之前元素兄弟之前点击的元素。但是,空白Text节点的存在使得它比传统脚本中的应用更令人讨厌。 Element Traversal API将使这更容易,但在浏览器中得到更广泛的支持之前,帮助函数是必要的,例如:

<div id="container">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

<script type="text/javascript">
    // Bind event to each line div
    //
    var div= firstElementChild(document.getElementById('container'));
    while (div!==null) {
        div.onclick= swapWithPreviousElement;
        div= nextElementSibling(div);
    }

    // Move element before its previous element sibling
    //
    function swapWithPreviousElement() {
        var previous= previousElementSibling(this);
        if (previous!==null)
            this.parentNode.insertBefore(this, previous);
    }


    // We've used some Element Traversal API methods but some
    // browsers don't support them yet. Provide wrapper functions
    // for compatibility.
    //
    function previousElementSibling(element) {
        if ('previousElementSibling' in element)
            return element.previousElementSibling;
        do
            element= element.previousSibling;
        while (element!==null && element.nodeType!==1);
        return element;
    }
    function nextElementSibling(element) {
        if ('nextElementSibling' in element)
            return element.nextElementSibling;
        do
            element= element.nextSibling;
        while (element!==null && element.nodeType!==1);
        return element;
    }
    function firstElementChild(element) {
        if ('firstElementChild' in element)
            return element.firstElementChild;
        var child= element.firstChild;
        while (child!==null && child.nodeType!==1)
            child= child.nextSibling;
        return child;
    }
</script>

答案 4 :(得分:2)

这适用于兄弟姐妹,应该适用于任何两个节点:

function swapElements(el1, el2) {
    let prev1 = el1.previousSibling;
    let prev2 = el2.previousSibling;

    prev1.after(el2);
    prev2.after(el1);
}

答案 5 :(得分:0)

交换任何节点,而不是兄弟姐妹,不是兄弟姐妹,没有临时节点,没有克隆,没有jquery ...... IE9 +

function swapNodes(n1, n2) {

    var p1 = n1.parentNode;
    var p2 = n2.parentNode;
    var i1, i2;

    if ( !p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1) ) return;

    for (var i = 0; i < p1.children.length; i++) {
        if (p1.children[i].isEqualNode(n1)) {
            i1 = i;
        }
    }
    for (var i = 0; i < p2.children.length; i++) {
        if (p2.children[i].isEqualNode(n2)) {
            i2 = i;
        }
    }

    if ( p1.isEqualNode(p2) && i1 < i2 ) {
        i2++;
    }
    p1.insertBefore(n2, p1.children[i1]);
    p2.insertBefore(n1, p2.children[i2]);
}