随机交换DOM(无jQuery)

时间:2019-01-17 13:42:59

标签: javascript html css dom

我的js应该进行html元素的随机交换。例如img或p。头寸互换有效,但是有一个我无法解释的错误。在我的示例html中只有2个p元素。交换工作了几次,但随后发生了一些奇怪的位置变化。

document.getElementById("pButton").addEventListener("click", () => {
  let max = document.querySelectorAll("p").length - 1;
  let min = 0;
  let x1 = Math.round((Math.random() * (max - min)) + min);
  let x2 = Math.round((Math.random() * (max - min)) + min);
  while (x1 === x2) {
    x2 = Math.round((Math.random() * (max - min)) + min);
  }
  let tmp1 = document.querySelectorAll("p")[x1];
  let tmp2 = document.querySelectorAll("p")[x2];
  let tmp1parent = tmp1.parentNode;
  let tmp2parent = tmp2.parentNode;
  let tmp1Index = 0;
  for (let a of tmp1parent.childNodes) {
    if (a === tmp1) {
      break;
    }
    tmp1Index += 1;
  }
  tmp2parent.insertBefore(tmp1, tmp2);
  tmp1parent.insertBefore(tmp2, tmp1parent.childNodes[tmp1Index]);
});
<div>
  <h1>List</h1>
  <p>p1</p>
  <ol>
    <li>first</li>
    <li>second</li>
  </ol>
  <a>example</a>
  <p>p2</p>
  <ol>
    <li>first</li>
    <li>second</li>
    <li>third</li>
  </ol>
  <a>example</a>
</div>
<button id="pButton">BUTTON</button>

1 个答案:

答案 0 :(得分:0)

我们在这里再次见面:)

document.getElementById("pButton").addEventListener("click", () => {
  let max = document.querySelectorAll("p").length - 1;
  let min = 0;
  let x1 = Math.round((Math.random() * (max - min)) + min);
  let x2 = Math.round((Math.random() * (max - min)) + min);
  while (x1 === x2) {
    x2 = Math.round((Math.random() * (max - min)) + min);
  }
  
  let tmp1 = document.querySelectorAll("p")[x1];
  let tmp2 = document.querySelectorAll("p")[x2];
  
  // it is nice to get direct reference, don't you think?
  let parentDiv = document.getElementById('parent');

  // get the previous element of first element you need to change
  let tmp1PrevEle = tmp1.nextElementSibling;
  // this is for the second one
  let tmp2PrevEle = tmp2.nextElementSibling;
  // insert both based on the previous and next elements
  parentDiv.insertBefore(tmp2, tmp1PrevEle);
  parentDiv.insertBefore(tmp1, tmp2PrevEle);
});
<div id="parent">
  <h1>List</h1>
  <p>p1</p>
  <ol>
    <li>first</li>
    <li>second</li>
  </ol>
  <a>example</a>
  <p>p2</p>
  <ol>
    <li>first</li>
    <li>second</li>
    <li>third</li>
  </ol>
  <a>example</a>
  <!-- just to see the randomness, I've added two more elements -->
  <p>p3</p>
  <ol>
    <li>first</li>
    <li>second</li>
    <li>third</li>
  </ol>
  <a>example</a>
  <p>p4</p>
  <ol>
    <li>first</li>
    <li>second</li>
    <li>third</li>
  </ol>
  <a>example</a>
</div>
<button id="pButton">BUTTON</button>

我在这里做什么

  1. nextElementSibling获取下一个元素,然后运行插入您需要移动的元素。
  2. 我正在复制两个节点的nextElementSibling,以便将来不再更改。

您的问题在这里。

let tmp1Index = 0;
  for (let a of tmp1parent.childNodes) {
    if (a === tmp1) {
      break;
    }
    tmp1Index += 1;
  }

该索引不可靠,因为一旦更改了项目,原始nodelist的位置可能会受到影响。