insertBefore не обновляет свойства rowIndex / nextSibling - PullRequest
0 голосов
/ 03 декабря 2018

Это может показаться глупым или даже тривиальным для большинства опытных пользователей, но я только что нашел несколько часов назад на интерфейсном javascript и должен сказать, что я немного озадачен поведением функции insertBefore javascript.

Мое намерение здесь простое и понятное: у меня есть таблица с ее строками и ячейками, и в каждой строке у меня есть ячейка с кнопкой, единственной целью которой является дублирование этой ячейки (со всем ее содержимым) и размещениеНовая дублированная ячейка рядом с исходной.

У меня есть функция javascript, например, такая:

// id -> the id of the table I want the row to be added
// caller -> the object of the element that called the function
function duplicateRow(id, caller)
{
    const table = document.getElementById(id);
    const row   = caller.parentNode.parentNode;  // Caller is always a button inside a cell inside a row
    const clone = row.cloneNode(true);

    table.insertBefore(clone, row.nextElementSibling);
}

Эта функция вызывается вот так (из выдержки из моего HTML):

<tr>
    <td>
        <input type="text" name="competence-name">
    </td>
    <td>
        <button name="duplicate-row-button" onclick="duplicateRow( 'competencies-table', this )"></button>
    </td>
</tr>

Итак, я ожидал бы, что при каждом нажатии кнопки дублирующейся строки будет создаваться точная копия строки, в которой нажимается кнопка, и добавьте его сразу после этой строки .

Моя проблема здесь не в дублировании (это делается правильно и гладко, как можно было бы ожидать), а в том, где новая строкапомещается:

  • Первый раз, когда есть только одна строка, она помещается в конец (поскольку nextSibling равно null).
  • Второй щелчоккнопка в первом ряду (несмотря на то, что теперь у нее есть брат или сестра сразу после нее), новый ряд снова помещается в конец таблицы (как если бы nextSibling для первого ряда все еще было null).
  • и т. Д. (Даже смешанные размещения происходят при смешивании дубликатов с вновь добавленными строками).

Разве свойства nextSibling и / или rowIndex не должныобновляется при добавлении нового узла в DOM?Есть ли способ заставить их обновить?Что я не так понял?Мой код, мое понимание того, как это должно работать?

Я, безусловно, открыт для любого возможного объяснения / решения / альтернативы для достижения того, что мне нужно, и спасибо всем заранее!

1 Ответ

0 голосов
/ 03 декабря 2018

Проблема заключается в том, что начальная строка таблицы заключена в элемент tbody (для которого можно не указывать как начальный, так и конечный тег), что требуется в соответствии с моделью содержимого таблиц.Однако, когда вы программно добавляете больше строк, они вставляются за пределы tbody, и ваша исходная строка является единственным дочерним элементом этого неявного tbody, поэтому дерево DOM выглядит следующим образом:

<table>
  <tbody>
    <tr></tr>
  </tbody>
  <tr></tr>
  <tr></tr>
</table>

Toрешить эту проблему, я предлагаю добавить клон к родительской строке клонированного:

function duplicateRow(caller){
  const row   = caller.parentNode.parentNode;  // Caller is always a button inside a cell inside a row
  const clone = row.cloneNode(true);

  row.parentNode.insertBefore(clone, row.nextElementSibling);
}
<table id="competencies-table">
  <tr>
    <td>
      <input type="text" name="competence-name">
    </td>
    <td>
      <button name="duplicate-row-button" onclick="duplicateRow( this )">Duplicate</button>
    </td>
  </tr>
</table>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...