【问题标题】:How to swap HTML elements in javascript?如何在 javascript 中交换 HTML 元素?
【发布时间】:2010-05-31 11:15:42
【问题描述】:

我正在使用经典的 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 交换

【问题讨论】:

  • 如果 div 1 被点击?
  • 如果 div 为 1 则不交换...
  • 只交换内容还是整个元素?
  • 如果你喜欢使用 jQuery:.replaceWith()

标签: javascript dom


【解决方案1】:

这段代码会做你想做的事(如果你想用第一个子元素交换选中的元素)。如果您想要其他内容,则需要更精确。

<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>

【讨论】:

  • 是的,和我想的差不多,但他并不总是想把它放在前面,他想把它放在前面的div之上。所以previousSibling。这对他来说是一个好的开始。
  • 在此代码中,当您单击 DIV 3 时,DIV 3 与 DIV 1 交换而不是 DIV 2..
  • 很高兴,您可以根据自己的情况对其进行修改
【解决方案2】:

元素的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);"

...虽然您可能想研究 DOM2 事件挂钩(addEventListener,或 IE 上的attachEvent)。

有点 OT,但我可以推荐使用几个可以让您的生活更轻松的可用库中的任何一个,例如 PrototypejQueryClosureany of several others。事实上,在早期版本中存在错误,因为距离我直接处理 DOM 已经那么了。 :-)

【讨论】:

  • 这几乎是已经回答的问题,但我投票给你是因为你给出了一个很好的完整答案。
  • 正是我想要的
【解决方案3】:

交换任何节点,不是兄弟节点,不是相邻兄弟节点,没有临时节点,没有克隆,没有 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]);
}

【讨论】:

  • 谢谢。这很有帮助。 isSameNode(或===)而不是isEqualNode(在所有地方)怎么样?
【解决方案4】:

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

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

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

【讨论】:

  • 我不确定如果其中一个元素没有先前的兄弟元素,它会起作用,因为元素之间没有空格
【解决方案5】:

从它的声音来看,您基本上只是想将 div 与它之前的 div 交换,因此与previousSibling 交换。您也许可以考虑使用insertBefore,但不要使用现有元素创建新元素。我不确定附加的事件会发生什么,如果它们会被正确复制。

【讨论】:

  • previousSibling 通常是空白文本节点(IE 除外)。
  • true,但只需测试 nodeType,如果它是 3,则获取 previousSibling(如果可用),直到找到 nodeType 1 之一。这并不太难。
【解决方案6】:

原则上,您只需在其前一个元素兄弟之前insertBefore您点击的元素。然而,空白文本节点的存在使得这比在传统脚本中更烦人。 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多