.insertBefore()在一个方向上工作,但不在另一个方向上工作

时间:2017-05-27 17:34:36

标签: javascript dom

我觉得这很愚蠢,因为我非常精通JavaScript,但我的咖啡因一定很低。在准备另一篇文章的答案时,我很难理解为什么我不能在表格中移动(使用parentNode.insertBefore(nodeToMove, referenceNode))一行,而向上移动则按预期工作。

正如您在console中看到的那样,所有变量都按预期和要求填充,我正在按照我的意愿到达正确的else if块。

注意:如果您打开实际的开发者控制台,则可以展开报告中列出的tr以验证是否正在引用正确的行。< / p>

&#13;
&#13;
// Get all the row elements and attach a click event handler for each of them
var rows = document.querySelectorAll("tr");

Array.prototype.slice.call(rows).forEach(function(r){
  r.addEventListener("click", swap);
});

function swap(evt) {
  // Get reference to the <tbody> element in the <table>
  var tbody = document.querySelector("table").querySelector("tbody");
 
  // Get the name of the class on the clicked element. This determines direction.
  var direction = evt.srcElement.classList.toString();
  
  // Get current row, previous row and next row references
  var cur = evt.currentTarget;
  var prev = cur.previousElementSibling;
  var next = cur.nextElementSibling;
  
  // DEBUGGING REPORT: ***********************************
  console.clear();
  console.log("Direction: " +  direction);
  console.log("Current row: ",  evt.currentTarget);
  console.log("Previous row: ", prev);
  console.log("Next row: ", next);
  // *****************************************************

  // Check to see if up was clicked and if there is a previous row to move clicked row to
  if(direction === "up" && prev){
     tbody.insertBefore(cur, prev);  // Move the current row up
  } else if(direction === "down" && next) {
     console.log("down was clicked and there is a next row to go after");
     // Move the current row down
     tbody.insertBefore(cur, next);  // <-- All variables are as expected, but no move!
  }
}
&#13;
span { text-decoration:underline; color:blue; cursor:pointer; }
&#13;
<table border=1>
    <tr>
        <td>Row A</td>
        <td>
            <span class="up">Up</span>
            <span class="down">Down</span>
        </td>
    </tr>
    <tr>
        <td>Row B</td>
        <td>
            <span class="up">Up</span>
            <span class="down">Down</span>
        </td>
    </tr>
    <tr>
        <td>Row C</td>
        <td>
            <span class="up">Up</span>
            <span class="down">Down</span>
        </td>
    </tr>
</table>
&#13;
&#13;
&#13;

修改

感谢@David Thomas的正确诊断。实际上,答案比他更容易,我只需要将参数交换为:insertBefore(next, cur);

&#13;
&#13;
// Get all the row elements and attach a click event handler for each of them
var rows = document.querySelectorAll("tr");

Array.prototype.slice.call(rows).forEach(function(r){
  r.addEventListener("click", swap);
});

function swap(evt) {
  // Get reference to the <tbody> element in the <table>
  var tbody = document.querySelector("table").querySelector("tbody");
 
  // Get the name of the class on the clicked element. This determines direction.
  var direction = evt.srcElement.classList.toString();
  
  // Get current row, previous row and next row references
  var cur = evt.currentTarget;
  var prev = cur.previousElementSibling;
  var next = cur.nextElementSibling;
  
  // DEBUGGING REPORT: ***********************************
  console.clear();
  console.log("Direction: " +  direction);
  console.log("Current row: ",  evt.currentTarget);
  console.log("Previous row: ", prev);
  console.log("Next row: ", next);
  // *****************************************************

  // Check to see if up was clicked and if there is a previous row to move clicked row to
  if(direction === "up" && prev){
     tbody.insertBefore(cur, prev);  // Move the current row up
  } else if(direction === "down" && next) {
     console.log("down was clicked and there is a next row to go after");
     // Move the current row down
     tbody.insertBefore(next, cur);  // <-- swap the arguments!
  }
}
&#13;
span { text-decoration:underline; color:blue; cursor:pointer; }
&#13;
<table border=1>
    <tr>
        <td>Row A</td>
        <td>
            <span class="up">Up</span>
            <span class="down">Down</span>
        </td>
    </tr>
    <tr>
        <td>Row B</td>
        <td>
            <span class="up">Up</span>
            <span class="down">Down</span>
        </td>
    </tr>
    <tr>
        <td>Row C</td>
        <td>
            <span class="up">Up</span>
            <span class="down">Down</span>
        </td>
    </tr>
</table>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:4)

由于这一行:

tbody.insertBefore(cur, next);

您在cur节点之前插入next节点,这意味着您将节点移动到它已占用的相同位置;所以请尝试:

tbody.insertBefore(cur, next.nextSibling);

&#13;
&#13;
// Get all the row elements and attach a click event handler for each of them
var rows = document.querySelectorAll("tr");

Array.prototype.slice.call(rows).forEach(function(r) {
  r.addEventListener("click", swap);
});

function swap(evt) {
  // Get reference to the <tbody> element in the <table>
  var tbody = document.querySelector("table").querySelector("tbody");

  // Get the name of the class on the clicked element. This determines direction.
  var direction = evt.srcElement.classList.toString();

  // Get current row, previous row and next row references
  var cur = evt.currentTarget;
  var prev = cur.previousElementSibling;
  var next = cur.nextElementSibling;

  // DEBUGGING REPORT: ***********************************
  console.clear();
  console.log("Direction: " + direction);
  console.log("Current row: ", evt.currentTarget);
  console.log("Previous row: ", prev);
  console.log("Next row: ", next);
  // *****************************************************

  // Check to see if up was clicked and if there is a previous row to move clicked row to
  if (direction === "up" && prev) {
    tbody.insertBefore(cur, prev); // Move the current row up
  } else if (direction === "down" && next) {
    console.log("down was clicked and there is a next row to go after");
    // Move the current row down
    tbody.insertBefore(cur, next.nextSibling); // <-- All variables are as expected, but no move!
  }
}
&#13;
span {
  text-decoration: underline;
  color: blue;
  cursor: pointer;
}
&#13;
<table border=1>
  <tr>
    <td>Row A</td>
    <td>
      <span class="up">Up</span>
      <span class="down">Down</span>
    </td>
  </tr>
  <tr>
    <td>Row B</td>
    <td>
      <span class="up">Up</span>
      <span class="down">Down</span>
    </td>
  </tr>
  <tr>
    <td>Row C</td>
    <td>
      <span class="up">Up</span>
      <span class="down">Down</span>
    </td>
  </tr>
</table>
&#13;
&#13;
&#13;

JS Fiddle demo