Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   динамическое создание элементов (https://javascript.ru/forum/events/10664-dinamicheskoe-sozdanie-ehlementov.html)

sg550 14.07.2010 15:38

динамическое создание элементов
 
При нажатии на ссылку рядом с ней должно появляться поле ввода, которое создается с помощью js. Возник вопрос: как желательнее делать - 1-ым методом (через DOM), или вторым (через innerHTML)? И что будет быстрее работать?

1-ый метод:
var Elem = {
	setAttrs : function(elem, attrs){
					for(var a in attrs){
						elem.setAttribute(a, attrs[a]);
					}
				},
	newElem : function(elem, attrs){
					var el = document.createElement(elem);
					Elem.setAttrs(el, attrs);
					return el;
				},
	newTxt : function(elem, txt){
					elem.appendChild(document.createTextNode(txt));
				}
}
var prompt 	= 	Elem.newElem('table', {class:'std_form', id:'quickreply'});
		prompt.innerHTML = "<tr><td></td><td></td></tr> <tr><td></td><td></td></tr> <tr><td></td><td></td></tr> <tr><td colspan=\"2\"></td></tr> <tr><td></td><td></td></tr> <tr><td></td><td></td></tr>";
		
		var name = Elem.newElem('input',{type : 'text', name : 'name', id : 'name', size:'30', value : "asdasd"});
		
		var subj = Elem.newElem('input', {type : 'text', name : 'subject', id : 'subj', size:'30', value : "фывыфв");
		var txtarea = Elem.newElem('textarea', {wrap : 'virtual',	name : 'message', id : 'quickreplytxt', cols:'60', rows:'10'});
		var submit = Elem.newElem('input', {type : 'submit', value: 'Отправить'});
		Elem.newTxt(prompt.cells[0], "Имя: ");
		Elem.newTxt(prompt.cells[4], "Тема комментария: ");
		
		prompt.getElementsByTagName('td')[1].appendChild(name);
		prompt.getElementsByTagName('td')[5].appendChild(subj);
		prompt.getElementsByTagName('td')[6].appendChild(txtarea);
		prompt.getElementsByTagName('td')[10].appendChild(submit);
		
		elem.appendChild(prompt);
		txtarea.focus();

2-ой метод:
var prompt  =   document.createElement('table');
prompt.innerHTML = "<tr><td>Имя:</td><td><input type=\"text\" name=\"name\" id=\"name\" /></td></tr><tr><td>Тема: </td><td><input type=\"text\" name=\"subject\" id=\"subj\" /></td></tr><tr><td><textarea wrap=\"virtual\" name=\"message\" id=\"quickreplytxt\" cols=\"60\" rows=\"10\"></textarea></td></tr><tr><td></td><td><input type=\"submit\" value=\"Отправить\" /></td></tr>";

exec 14.07.2010 15:51

А потестить не судьба?

x-yuri 14.07.2010 21:35

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

а по поводу производительности: доделываешь страничку, а _потом_ начинаешь искать _узкие места_

Маэстро 29.07.2010 20:40

Прервый метод (DOM) - это программирование. Второй (HTML) - это "разметка текста". Лично я склоняюсь к программированию!

При небольших количествах элементов на странице оба способа практически эквивалентны. Причем способ с innerHTML иногда выглядит читабельнее; и его можно быстрее написать.
Однако, на больших количествах элементов появляется разница.
Можете попробовать нарисовать таблицу 100 строк х 100 столбцов. По моим оценкам var o=getElementById (с которым прийдется работать при innerHTML ) работает заметно медленнее, чем прямое указание javascript объекта var o=someobject
var someobject = document.createElement('div');

Особенно торможение заметно в IE.
Хотя теоретически по скорости должны работать одинаково.

Поэтому лучше DOM. Но... существует ряд проблем, которые без innerHTML не решишь.
Например, Вы хотите создать форму с элементом "input" типа "file":
var f=document.createElement('form');
f.method='POST';
f.action='lalala.php';
f.enctype='multipart/form-data';
... ...

Это работать не будет в IE. У него глюк с enctype.
Как быть? - Только вот так:
o.innerHTML='<form enctype="multipart/form-data"></form>';
... ...

рони 29.07.2010 23:26

Маэстро,
а так ? ))
var f = document.createElement("form");
f.method = "POST";
f.action = "lalala.php";
f.setAttribute("enctype", "multipart/form-data");
f.setAttribute("encoding", "multipart/form-data");
var i = document.createElement("input");
i.setAttribute("type", "file");
f.appendChild(i);
document.body.appendChild(f);

x-yuri 30.07.2010 03:09

Цитата:

Сообщение от Маэстро
Однако, на больших количествах элементов появляется разница.
Можете попробовать нарисовать таблицу 100 строк х 100 столбцов. По моим оценкам var o=getElementById (с которым прийдется работать при innerHTML ) работает заметно медленнее, чем прямое указание javascript объекта var o=someobject

во-первых, это же не ядро какого-нибудь фреймворка, которое неизвестно в каких условиях работать будет. И то я не думаю, что такие вещи оптимизируются по принципу "оптимизируем все, что движется". Так вот, это вполне конкретный случай, и можно померять, что тормозит и сколько можно выжать за счет оптимизации, если так интересно. Только надо осознавать, что ускорение в 1 мс пользователь не заметит
во-вторых, почему прийдется работать с getElementById и о каком прямом указании javascript-объекта идет речь? Здесь, кстати, с getElementById работать не пришлось

Цитата:

Сообщение от Маэстро
Хотя теоретически по скорости должны работать одинаково.

In theory there is no difference between theory and practice.
In practice there is.
Yogi Berra
;)

Kolyaj 30.07.2010 07:31

Цитата:

Сообщение от Маэстро
Однако, на больших количествах элементов появляется разница.

О да, и какая разница! При создании объёмного HTML кода DOM методами у вас такая неподдерживаемая каша в коде будет, мама не горюй.

Цитата:

Сообщение от Маэстро
Прервый метод (DOM) - это программирование. Второй (HTML) - это "разметка текста".

И то, и другое -- разметка.

Маэстро 30.07.2010 13:19

Цитата:

Сообщение от рони;
f.setAttribute("enctype", "multipart/form-data");
f.setAttribute("encoding", "multipart/form-data");

а так ? ))

Да, Вы правы. Установка свойств с помощью setAttribute решает проблему в IE; причём устанавливать надо и enctype, и encoding.
Только недолюбливаю я setAttribute()... или он меня недолюбливает...? ;)

Kolyaj 30.07.2010 13:21

Цитата:

Сообщение от Маэстро
Только недолюбливаю я setAttribute()... или он меня недолюбливает...?

http://xpoint.ru/know-how/JavaScript/Atributyi?8
Любите друг друга.

Маэстро 30.07.2010 13:49

Цитата:

Сообщение от x-yuri
во-первых, это же не ядро какого-нибудь фреймворка, которое неизвестно в каких условиях работать будет.

-привычка писать быстроработающий и кроссбраузерный код позволит в дальнейшем программисту накопить опыт и написать фреймворк. А мало ли... может и прийдётся...?

Цитата:

Сообщение от x-yuri
Только надо осознавать, что ускорение в 1 мс пользователь не заметит

-речь идёт не об ускорении в 1 мс, а (грубо говоря) замедлении в 1 мс НА КАЖДЫЙ добавленный элемент. И если элементов на странице 1000, то, замедление хорошо заметно.

Цитата:

Сообщение от x-yuri
во-вторых, почему прийдется работать с getElementById и о каком прямом указании javascript-объекта идет речь? Здесь, кстати, с getElementById работать не пришлось

-покажу на моём примере с таблицей 100х100.
Пользователь прописывает формулу, в которой указывает, что типа возьми значение из ячейки талицы строки №5, столбца №30 и прибавь к ячейке 10/40.
Как бы решить такую задачку? Очевидно что каждую ячейку надо снабдить своим id, каждый из которых будет вида "cell_xxx_yyy", где xxx-номер строки, а yyy-номер столбца. Дальше искать эти ячейки методом
getElementById('cell_5_30') и getElementById('cell_10_40')
Это при создании таблицы с помощью HTML.

Если же всю таблицу создавать "на лету" с помощью javascript, то id ячейкам можно не задавать, т.к. мы имеем ПРЯМЫЕ УКАЗАТЕЛИ на ячейки таблицы:
o_1_1= document.createElement("div");
o_1_2= document.createElement("div");
o_1_3= document.createElement("div");
...
и по ним можем сразу обращаться к содержимому ячеек.

Маэстро 30.07.2010 13:56

Цитата:

Сообщение от Kolyaj
О да, и какая разница! При создании объёмного HTML кода DOM методами у вас такая неподдерживаемая каша в коде будет, мама не горюй.

Не понял, почему каша? Все созданные объекты хранятся либо в нумерованном массиве, либо в одном общем объекте, либо снабжаются уникальными именами (переменных).

Цитата:

Сообщение от Kolyaj
И то, и другое -- разметка.

Не хотелось бы вдаваться в глубокую философию, но...
По-моему, написание функций создания (DOM) объектов и управления ими - это программирование.
Что есть по-Вашему программирование? Написание функций сложения 2+3?

Kolyaj 30.07.2010 13:56

Цитата:

Сообщение от Маэстро
Очевидно что каждую ячейку надо снабдить своим id, каждый из которых будет вида "cell_xxx_yyy", где xxx-номер строки, а yyy-номер столбца.

Очевидно надо подучить DOM. table.rows[4].cells[29]

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

Kolyaj 30.07.2010 14:06

Цитата:

Сообщение от Маэстро
Не понял, почему каша?

Ну это вы, наверно, про таблицу всё. А вы попробуйте произвольную разметку посоздавать с дивами, с инлайн-элементами, с картинками. И что у вас получится.

Маэстро 30.07.2010 14:08

Цитата:

Сообщение от Kolyaj (Сообщение 65642)
Очевидно надо подучить DOM. table.rows[4].cells[29]

я знаю, что такое table.... rows ... cells
а также t.insertRow() ... r.insertCell()...
Пример с таблицей я привёл очень упрощённый. В задаче, с которой приходилось сталкиваться мне, объекты находились не в строго структурированной таблице, к которой можно было бы обратиться по номеру строки и столбца. Точнее, они могли представлять сразу группы объектов, которые в свою очередь содержали другие группы...

Маэстро 30.07.2010 14:15

Цитата:

Сообщение от Kolyaj (Сообщение 65649)
Ну это вы, наверно, про таблицу всё. А вы попробуйте произвольную разметку посоздавать с дивами, с инлайн-элементами, с картинками. И что у вас получится.

Пробовал. Вот: http://gigalit.com.ua

Kolyaj 30.07.2010 14:22

// создание wincontainer выше
wincontainer.innerHTML='<div class="videowin"  onmousedown="return GigDrag(event,this,'+wh+');"</div>';  // вся соль - в строке return... ;)
winobj=wincontainer.firstChild;
wincontainer.removeChild(winobj);
G.videowin=winobj;


if (bg0)                                                                        // фон 0
{
obj=d.createElement('div'); obj.className='vw0'; winobj.appendChild(obj);
G['videowinbg0']=obj;
}

if (bg1)
{
obj=d.createElement('div'); obj.className='vw1';
winobj.appendChild(obj);
G.videowinver=obj;
}


if (bg2)
{
obj=d.createElement('div'); obj.className='vw2';
winobj.appendChild(obj);
G.videowinhor=obj;
}


obj=d.createElement('div');                                                     // Tttle Window
obj.className='vw4';
obj.innerHTML=title;
if (title != '') obj.style.display='block';
winobj.appendChild(obj);
G.videowintitle=obj;


obj=d.createElement('div');                                                     // внутренняя часть окна
obj.className='vw5';
winobj.appendChild(obj);
G.videowininside=obj;


obj=d.createElement('div');                                                     // кнопка закрытия окна (vw6 for IE!)
obj.className='vw6';
 objclose=d.createElement('img');
 objclose.className='vw7';
 objclose.onclick=function() {closevideowin(wh);}
 objclose.align='right';
 objclose.src = 'close7.jpg';
 if (IE) objclose.style.marginRight=4;
obj.appendChild(objclose);
if (Fclose) obj.style.display='block';
winobj.appendChild(obj);
G.videowinclose=obj;


obj=d.createElement('img');                                                     // картинка "loading"
obj.className='vw8';
obj.src = 'loading42.gif';
  obj.id='videowinloading'+wh;
if (Floading) obj.style.display='block';
winobj.appendChild(obj);
G.videowinloading=obj;


G.NoMoveIn = [];
G.videowin = winobj;
d.body.appendChild(winobj);


Для поддержки вёрстки нужно понимать её структуру. Грубо говоря, понимать, какой html-код строит картинку на экране. Кто по данному коду может восстановить html-код?

Маэстро 30.07.2010 14:33

Цитата:

Сообщение от Kolyaj
Для поддержки вёрстки нужно понимать её структуру. Грубо говоря, понимать, какой html-код строит картинку на экране. Кто по данному коду может восстановить html-код?

1. Вы выхватили кусочек кода с главной страницы, который уже устарел, не очень удачный и был взят из другого старого проекта. бОльшая же часть js-кода лежит отдельно и подгружается по мере запуска пользователем разных функций. В подгружаемых модулях панели "конструируются" из отдельных готовых блоков (юнитов).
Например, вот так:
var s='<b>Шаг 1.</b> Выберите картинку из предложенного списка';
m.s1 = settextbgpanelunit(0,v,360,h, 'mcellbg','mtext', 10,5, s);
m.s1.container.onclick = step1;
p.appendChild(m.s1.container);

s='<b>Шаг 2.</b> Введите поздравительный текст';
m.s2 = settextbgpanelunit(0,v*2,360,h, 'mcellbg','mtext', 10,5, s);
m.s2.container.onclick = step2;
p.appendChild(m.s2.container);

s='<b>Шаг 3.</b> или выберите текст из предложенного списка';
m.s3 = settextbgpanelunit(0,v*3,360,h, 'mcellbg','mtext', 10,5, s);
m.s3.container.onclick = step3;
p.appendChild(m.s3.container);

s='<b>Шаг 4.</b> Определите шрифт текста, размер и цвет';
m.s4 = settextbgpanelunit(0,v*4,360,h, 'mcellbg','mtext', 10,5, s);
m.s4.container.onclick = step4;
p.appendChild(m.s4.container);

s='<b>Шаг 5.</b> Выберите музыкальное сопровождение';
m.s5 = settextbgpanelunit(0,v*5,360,h, 'mcellbg','mtext', 10,5, s);
m.s5.container.onclick = step5;
p.appendChild(m.s5.container);

s='<b>Шаг 6.</b> Добавьте прикольный смайлик к открытке';
m.s6 = settextbgpanelunit(0,v*6,360,h, 'mcellbg','mtext', 10,5, s);
m.s6.container.onclick = step6;
p.appendChild(m.s6.container);

s='<b>Шаг 7.</b> Введите адрес получателя открытки';
m.s7 = settextbgpanelunit(0,v*7,360,h, 'mcellbg','mtext', 10,5, s);
m.s7.container.onclick = step7;
p.appendChild(m.s7.container);


2. Если оочень грубо говоря, ;) то "Кто по данному коду может восстановить html-код" - пусть это Вас не беспокоит. Для этого есть люди. Да и зачем его восстанавливать?

Kolyaj 30.07.2010 14:39

Цитата:

Сообщение от Маэстро
Вы выхватили кусочек кода с главной страницы, который уже устарел и не очень удачный

Уж какой нашёл, и его-то не так просто было найти.

Вы не привели примера создания элементов.

Цитата:

Сообщение от Маэстро
Для этого есть люди.

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

Цитата:

Сообщение от Маэстро
Да и зачем его восстанавливать?

Если вёрстка "поплывёт", или её нужно будет чуть-чуть поменять, то для этого нужно представлять текущий html. А это сделать затруднительно.

Цитата:

Сообщение от Маэстро
пусть это Вас не беспокоит

Меня это не беспокоит.

x-yuri 30.07.2010 14:43

Цитата:

Сообщение от Маэстро
-привычка писать быстроработающий и кроссбраузерный код позволит в дальнейшем программисту накопить опыт и написать фреймворк. А мало ли... может и прийдётся...?

привычка искать узкие места позволит программисту в дальнейшем писать быстроработающий код

Цитата:

Сообщение от Маэстро
-речь идёт не об ускорении в 1 мс, а (грубо говоря) замедлении в 1 мс НА КАЖДЫЙ добавленный элемент. И если элементов на странице 1000, то, замедление хорошо заметно.

Цитата:

Сообщение от Маэстро
-покажу на моём примере с таблицей 100х100.

в том то и дело, что пример синтетический. Давайте сравним на реальном примере, вы ставите задачу, мы ее реализовываем и сравниваем результаты ;)

Маэстро 30.07.2010 15:23

Цитата:

Сообщение от x-yuri (Сообщение 65657)
в том то и дело, что пример синтетический. Давайте сравним на реальном примере, вы ставите задачу, мы ее реализовываем и сравниваем результаты ;)

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

Хотя, думаю, что Google, или Мicrosoft сделают это быстрее...

x-yuri 30.07.2010 16:37

Цитата:

Сообщение от Маэстро
Реальный пример я показать не могу

да при чем тут этот сайт? Просто делаете скриншот с описанием, из каких элементов это будет состоять (если не очевидно). Причем чтобы это было похоже на что-то реальное, а не таблица 100x100. Нужно динамически сгенерировать верстку. Вы и я делаем два варианта и сравниваем производительность

Маэстро 30.07.2010 18:40

Цитата:

Сообщение от x-yuri (Сообщение 65673)
да при чем тут этот сайт? Просто делаете скриншот с описанием, из каких элементов это будет состоять (если не очевидно). Причем чтобы это было похоже на что-то реальное, а не таблица 100x100. Нужно динамически сгенерировать верстку. Вы и я делаем два варианта и сравниваем производительность

Хорошо. Попробую описать. Только навряд ли Вы захотите это сделать из спортивного интереса.
Понимаете, у меня как бы в принципе нет HTML-вёрстки в привычном понимании этого слова при разработке сайта.
Все объекты хранятся в базе. Предположим их два типа: автомобили и контейнеры (морские). Каждый объект обладает набором свойств. Часть свойств одинакова (например, координаты и название), а часть свойств разные. Причём те свойства, которые разные - это не свойства DOM-объектов, а бизнес-свойства. Например, у машины есть марка и кубометраж. У контейнера есть тоннаж и условия инкотермс (FOB, CIF, DDP,...) которых нет у автомобиля. Все бизнес-свойства должны в конечном итоге отображаться на экране в виде картинок, текстов, таблиц, полей ввода.... То есть, каждый объект на экране - это комплект из table, div, img и т.д.
Свойства объектов не верстаются (как на типичных сайтах), а добавляются самими пользователями, для чего имеется набор "стандартных" заготовок.

Как это реализовать?
Вариант первый:
формировать весь html-текст на сервере (например, PHP) и отправлять клиенту. Объем получится не менее 1 Мегабайта. Все объекты прийдётся снабдить уникальными id, для дальнейшего оперирования ими.

Вариант второй:
Формировать DOM-объекты всего этого пространства с помощью javascript на клиенте; клиенту отправлять только массив чисто данных (любым транспортным механизмом).

В заключение добавлю, что все объекты отображаются на некой "карте местности", размер которой 30000х30000 пикселей. И не думайте, что я ошибся в ноликах ;)

x-yuri 01.08.2010 23:48

ну так это же совсем другой случай, в отличие от указанного в первом сообщении топика. Есть три вида компонентов: карта, автомобили, контейнеры. У каждого минимум разметки, судя по описанию, т.е. по сути каждый из них - это один абсолютно-спозиционированный div. Причем карта просто содержит коллекцию автомобилей/контейнеров, т.е. нету никакого сложного шаблона, по которому автомобили/контейнеры включаются в карту. Создавать разметку каждого компонента проще создавать с помощью createElement, потому что каждый элемент - это один div

в общем, чем сложнее шаблон, тем лучше подходит innerHTML

p.s. мы собирались сравнивать innerHTML vs createElement/appendChild...

Маэстро 02.08.2010 16:36

Цитата:

Сообщение от x-yuri (Сообщение 65919)
... т.е. нету никакого сложного шаблона, по которому автомобили/контейнеры включаются в карту.

ну да

Цитата:

Сообщение от x-yuri (Сообщение 65919)
Создавать разметку каждого компонента проще создавать с помощью createElement, потому что каждый элемент - это один div

так а я о чём говорю? именно о том, что лучше createElement, а не innerHTML.
подчеркну только, что что каждый элемент - это не один div, а один div, содержащий в себе ещё кучу div_ов и других элементов.

а главное, я утверждал, что при использовании innerHTML приходится снабжать элементы идентификаторами, а потом обращаться к ним с помощью GetElementByID(). и при их большом количестве начинается торможение

x-yuri 02.08.2010 17:18

Цитата:

Сообщение от Маэстро
так а я о чём говорю? именно о том, что лучше createElement, а не innerHTML

а я говорю, что чем сложнее шаблон, тем лучше подходит innerHTML

Цитата:

Сообщение от Маэстро
подчеркну только, что что каждый элемент - это не один div, а один div, содержащий в себе ещё кучу div_ов и других элементов

если там еще куча div'ов и других элементов и вы говорите, что с innerHTML медленнее, давайте картинку с описанием, сравним производительность генерации разметки

Цитата:

Сообщение от Маэстро
а главное, я утверждал, что при использовании innerHTML приходится снабжать элементы идентификаторами, а потом обращаться к ним с помощью GetElementByID(). и при их большом количестве начинается торможение

не обязательно снабжать их id

x-yuri 02.08.2010 17:34

по вашему опсанию получается где-то так
var Map = new Class({
    initialize: function(){
        this._objs = [];
        this._el = new Element('div');
    },

    addObject: function( o ){
        this._objs.push( o )
        o.inject(this._el);
    }
});

var Car = new Class({
    initialize: function(){
        this._el = new Element('div');
    }
});

var map = new Map();
var car = new Car();
map.addObject(car);

если же там не просто div, то
this._el = new Element('div')

превращается в что-то типа
this._el = template(
    '<table>'+
        '<tr><td>Имя:</td>'+
            '<td><input type="text" name="name" id="name" /></td>'+
        '</tr>'+
        '<tr><td>Тема: </td>'+
            '<td><input type="text" name="subject" id="subj" /></td>'+
        '</tr>'+
        '<tr><td><textarea wrap="virtual" name="message" id="quickreplytxt" cols="60" rows="10"></textarea></td></tr>'+
        '<tr><td></td>'+
            '<td><input type="submit" value="Отправить" /></td>'+
        '</tr>'+
    '</table>');

Маэстро 02.08.2010 18:10

Цитата:

Сообщение от x-yuri (Сообщение 66035)
не обязательно снабжать их id

Вы это написали, а потом в своём примере все три поля input снабдили id! :)
(id="name", name="subject", id="quickreplytxt")
Зачем id? -затем, чтобы взять значение переменной, или прописать его туда.

теперь насчёт "this._el = ..."
Когда вся эта "Карта полётов" уже создана (а так её называет Заказчик), то все ссылки "this" уже забыты. И вот наступает момент, когда поступает информация, что груз номер 5 едет в автомобилях 7,8 и 15 (к примеру). Как обратиться к элементам 7,8 и 15? Очевидно, что либо снабдить их id_шками типа id=object_7, id=object_8, id=object_15. Либо, ещё при создании запомнить все созданные this._el в отдельном массиве например, map[...] (можно в объекте map{} ) и тогда при поиске элементов делать не
o=document.getElementById('object_7')
a
o=map[7]; - вот это я и называл прямым доступом к объектам.

x-yuri 02.08.2010 18:29

Цитата:

Сообщение от Маэстро
Вы это написали, а потом в своём примере все три поля input снабдили id!

это был копипаст из поста ТС

Цитата:

Сообщение от Маэстро
теперь насчёт "this._el = ..."

использование innerHTML не означает использование getElementById, и вполне совместимо с хранением ссылок на нужные DOM-объекты в javascript-объектах

x-yuri 02.08.2010 18:34

продолжая пример (если нужно обращаться к textarea)
var Car = new Class({ 
    initialize: function(){ 
        this._el = template( 
            '<table>'+ 
                '<tr><td>Имя:</td>'+ 
                    '<td><input type="text" name="name" id="name" /></td>'+ 
                '</tr>'+ 
                '<tr><td>Тема: </td>'+ 
                    '<td><input type="text" name="subject" id="subj" /></td>'+ 
                '</tr>'+ 
                '<tr><td><textarea wrap="virtual" name="message" id="quickreplytxt" cols="60" rows="10"></textarea></td></tr>'+ 
                '<tr><td></td>'+ 
                    '<td><input type="submit" value="Отправить" /></td>'+ 
                '</tr>'+ 
            '</table>');
    },

    _textarea: function(){
        if( ! this._textareaEl )
            this._textareaEl = this._el.getElement('textarea');
        return this._textareaEl;
    }
});


Часовой пояс GMT +3, время: 01:43.