Эффективный способ ООП динамически генерировать элементы DOM с помощью JavaScript?
Я работаю над созданием более эффективной методологии создания динамически генерируемых элементов DOM через JavaScript. Это то, что я собираюсь добавить в свою собственную среду JS позже. Ищу других разработчиков ООП, которые могли бы помочь лучше уточнить то, что у меня есть.
Вот ссылка на рабочий CodePen: http://codepen.io/DaneTheory/pen/yeLvmm/
Вот JS:
function CreateDOMEl() {};
CreateDOMEl.prototype.uiFrag = document.createDocumentFragment();
CreateDOMEl.prototype.elParent = function(elParent, index) {
this.elParent = document.getElementsByTagName(elParent)[index];
}
CreateDOMEl.prototype.elType = function(type) {
newEl = document.createElement(type);
this.uiFrag.appendChild(newEl);
}
CreateDOMEl.prototype.elContent = function(elContent) {
this.elContent = elContent;
newEl.textContent = elContent;
}
CreateDOMEl.prototype.buildEl = function() {
this.elParent.appendChild(this.uiFrag);
}
var div = new CreateDOMEl();
div.elParent('body', 0);
div.elType('DIV');
div.elContent('OK');
div.buildEl();
console.log(div);
var bttn = new CreateDOMEl();
bttn.elParent('body', 0);
bttn.elType('BUTTON');
bttn.elContent('SUBMIT');
bttn.buildEl();
console.log(bttn);
И немного CSS для отображения элементов на странице:
div {
width:100px;
height:100px;
border: 1px solid red;
}
Мои мысли:
- Для производительности используйте прототип для построения методов вместо размещения всей логики в конструкторе.
- Вместо непосредственного добавления элементов на страницу, добавьте к одному фрагменту документа. После того, как элемент создан как Doc Frag, добавьте Doc Frag к DOM. Мне нравится этот метод для производительности, но я хотел бы улучшить его. Любые полезные реализации requestnimationFrame, или использование диапазона и других версий метода фрагмента документа?
- Глупо, но я думаю, что для отладки было бы неплохо увидеть сгенерированный тип Element в свойстве Object в журнале консоли. На данный момент консоль, регистрирующая созданный элемент, покажет элементы parent и текстовое содержимое. Было бы здорово показать тип элементов.
Создание более одного элемента за раз - это еще одна функциональность, которую я хотел бы предложить в качестве опции. Например, при создании элемента div создается один элемент div. Какой хороший способ добавить еще один дополнительный метод для создания нескольких экземпляров div.
div.elType('DIV'); // After calling the elType method, do something like this: div.elCount(20); // This would create 20 of the same divs
Наконец, хороший чистый способ необязательно добавлять атрибуты (то есть: классы, идентификатор, значение, заполнитель, пользовательские атрибуты, атрибуты data-* и т. Д.). У меня есть хорошая вспомогательная функция, которую я использую, которая добавляет несколько атрибутов к элементу в виде буквального синтаксиса объекта. Добавление этого в качестве метода конструктора было бы идеальным. Вот эта функция:
function setAttributes(el, attrs) { for(var key in attrs) { el.setAttribute(key, attrs[key]); } } // A use case using the above // function would be: var anInputElement = document.createElement("TEXTAREA"); setAttributes(anInputElement, { "type": "text", "id": "awesomeID", "name": "coolName", "placeholder": "Hey I'm some placeholder example text", "class": "awesome" }); // Which creates the following HTML snippet: <textarea type="text" id="awesomeID" name="coolName" placeholder="Hey I'm some placeholder example text" class="awesome">
Как примечание: теперь мы понимаем, что вышеприведенную вспомогательную функцию нужно переписать, чтобы можно было создать несколько классов.
1 ответ
С уважением, я верю, что вы можете обдумать это. Просто используйте инструменты, доступные в JavaScript, и все готово. С точки зрения производительности, компьютеры настолько быстро запускают ваш JavaScript, что вы (и я) не способны воспринимать или даже понимать скорость. Вот, например, как добавить ссылку в навигационное меню MDL. Это просто ванильный JS. Не забудьте добавить слушателей событий.
function navMenuAdd(type,text){
var newAnchor = doc.createElement("anchor");
newAnchor.classList.add('mdl-navigation__link');
newAnchor.classList.add(type);
newAnchor.href = "javascript:void(0)";
var anchorContent = doc.createTextNode(text);
newAnchor.appendChild(anchorContent);
newAnchor.addEventListener('click', navMenuClickHandler, false);
//newAnchor.style.display = 'none';
if (type === 'Thingy A'){
//insertAfter(newAnchor, navMenuCredentials);
navMenuCredentialsPanel.appendChild(newAnchor);
} else if (type === 'Thingy B'){
//insertAfter(newAnchor, navMenuDevices);
navMenuDevicesPanel.appendChild(newAnchor);
}
}