Самый эффективный способ создания и вложения div с помощью appendChild с использованием * plain * javascript (без библиотек) - PullRequest
3 голосов
/ 20 апреля 2010

Есть ли более эффективный способ написания следующего кода appendChild / nesting?

var sasDom, sasDomHider;
var d = document;
var docBody = d.getElementsByTagName("body")[0];
var newNode = d.createElement('span');
var secondNode = d.createElement('span');

// Hider dom
newNode.setAttribute("id", "sasHider");
docBody.appendChild(newNode);
sasDomHider = d.getElementById("sasHider");

// Copyier dom
secondNode.setAttribute("id", "sasText");
sasDomHider.appendChild(secondNode);
sasDom = d.getElementById("sasText");

Ответы [ 6 ]

5 голосов
/ 20 апреля 2010

Хорошо, вопрос изменился.Мля.Вот новый ответ:

Вы можете немного повысить эффективность выполнения, построив ветвь, прежде чем добавлять ее в дерево DOM (браузер не будет пытаться что-либо восстановить во время сборки).И немного в плане эффективности обслуживания за счет уменьшения количества лишних переменных:

var d = document;
var docBody = d.getElementsByTagName("body")[0];

// Copyier dom
var sasDom = d.createElement('span');
sasDom.setAttribute("id", "sasText");

// Hider dom
var sasDomHider = d.createElement('span');
sasDomHider.setAttribute("id", "sasHider");

sasDomHider.appendChild(sasDom); // append child to parent
docBody.appendChild(sasDomHider); // ...and parent to DOM body element

Оригинальный ответ:

Вы пытаетесь вставить один и тот же элемент дважды, вто же место ...

var newNode = d.createElement('span');

... Это единственное место, где вы создаете элемент в этом коде.Так что создан только один элемент.И вы вставляете его после последнего дочернего элемента в теле:

docBody.appendChild(newNode);

Пока все хорошо.Но затем вы модифицируете атрибут и пытаетесь вставить тот же самый узел снова, после последнего потомка sasDomHider ... который сам по себе!Естественно, вы не можете сделать узел своим собственным потомком.

Действительно, вы просто хотите создать новый элемент и работать с ним:

newNode = d.createElement('span');
newNode.setAttribute("id", "sasText");
sasDomHider.appendChild(newNode);
// the next line is unnecessary; we already have an element reference in newNode
// sasDom = d.getElementById("sasText");
// ... so just use that:
sasDom = newNode;
1 голос
/ 20 апреля 2010

Есть несколько способов сделать это более эффективным (с точки зрения производительности и размера кода / читабельности), большинство из которых уже были рассмотрены:

// Hider dom
var sasDomHider = document.createElement('span');
sasDomHider.id = "sasHider";

// Copier dom
var sasDom = document.createElement('span');
sasDom.id = "sasText";

sasDomHider.appendChild(sasDom);
document.body.appendChild(sasDomHider);
  • Получает тело, используя document.body
  • Использует только одну переменную для узлов, которые вы создали
  • Удаляет строки getElementById, так как они дают вам ссылки на те же элементы, которые у вас уже были
  • Использует свойство id элементов, а не setAttribute, что является ненужным вызовом функции и более подробным
  • Создает всю ветвь, добавляемую к документу перед его добавлением, таким образом избегая ненужной перекраски / перекомпоновки
  • Удаляет d как псевдоним для document: нет необходимости хранить другую ссылку на документ, висящий вокруг
  • Удаляет переменную docBody, поскольку вы используете ее только один раз
1 голос
/ 20 апреля 2010

Вам не нужно снова искать узлы:

var d = document;
var docBody = d.body;
var sasDomHider = d.createElement('span');
var sasDom = d.createElement('span');

// Hider dom
sasDomHider.setAttribute("id", "sasHider");
docBody.appendChild(sasDomHider);

// Copyier dom
sasDom.setAttribute("id", "sasText");
sasDomHider.appendChild(sasDom);
1 голос
/ 20 апреля 2010

Это потому, что newNode ссылается на экземпляр HtmlElement, который вы пытаетесь вставить в два разных места в DOM. Вам нужно будет каждый раз создавать новый элемент (или использовать cloneNode , но существуют расхождения между браузерами в том, как это работает).

Как-то так должно работать

var sasDom,        
    d = document,
    docBody = d.getElementsByTagName("body")[0],
    sasDomHider = d.createElement('span');

// Hider dom
sasDomHider.setAttribute("id", "sasHider");
docBody.appendChild(sasDomHider);

// Copyier dom
sasDom = sasDomHider.cloneNode(true);
sasDom.setAttribute("id", "sasText");
sasDomHider.appendChild(sasDom);
// job done. sasDomHider and sasDom still reference the 
// created elements.
0 голосов
/ 20 апреля 2010

В вашем примере объекты, на которые ссылаются newNode, sasDomHider и sasDom, являются одинаковыми, и все они указывают на один элемент DOM. Вы пытаетесь поместить это в двух местах одновременно. Вам нужно клонировать его или просто сделать новый <span> для второго экземпляра. Простого изменения атрибута id недостаточно (вы изменяете id того атрибута, который уже есть в документе).

0 голосов
/ 20 апреля 2010

Как правило, один из наборов innerHTML тела с требуемым HTML будет наиболее эффективным методом.

, например

document.body.innerHTML = document.body.innerHTML + '<span id="foo"></span><span id="bar"></span>';
...