Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Клонирование нод с заменой атрибутов 
:(
    Опции темы
dm9
Дата 2.10.2007, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дмитрий Копытин
****


Профиль
Группа: Vingrad developer
Сообщений: 3876
Регистрация: 22.7.2002
Где: Москва

Репутация: нет
Всего: 137



Добрый день.

Мне необходимо решить следующую задачу: клонирование ноды со всеми потомками с последующей подменой атрибутов name и id всех этих потомков. Если более широко описывать задачу, есть некоторый набор параметров (input-ов), которые описывают некоторый документ. Необходимо на одной странице дать пользователю возможность создания любого количества таких документов. При этом все документы находятся в одной форме, и при сабмите input-ы разных документов должны отправиться на сервер, очевидно, с разными именами (префиксами).

Есть несколько вариантов.
1. Использование готового решения. Подскажете, какого?
2. Рекурсивное клонирование через DOM. Есть ли здесь подводные камни?
3. Работа через innerHTML с заменой атрибутов регулярками ;)

Какой вариант использовали бы Вы, и почему? Возможно, я какого-то варианта ещё не учёл?

AJAX и создание нод заранее прошу не предлагать, интересует чисто клиентское JS-решение. Причина: AJAX для нас слишком дорогой, создание достаточного количества нод заранее (на сервере) уже сделали, генерация получается слишком долгая. smile

PM MAIL ICQ   Вверх
dsCode
Дата 2.10.2007, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



третий вариант (т.к. быстрее innerHTML будет работать), но вперемешку со вторым


--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
dm9
Дата 2.10.2007, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дмитрий Копытин
****


Профиль
Группа: Vingrad developer
Сообщений: 3876
Регистрация: 22.7.2002
Где: Москва

Репутация: нет
Всего: 137



А вперемешку -- это как? Клонируемые ноды должны по вёрстке располагаться одна под другой.
PM MAIL ICQ   Вверх
cruelangel
Дата 2.10.2007, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 319
Регистрация: 12.9.2007

Репутация: 4
Всего: 8



> очевидно, с разными именами (префиксами)

совершенно не очевидно smile

если на сервере php, то он умеет образовывать массивы из такого:

<input name="name[]" value="a" />
<input name="name[]" value="b" />
<input name="name[]" value="c" />

если что-то другое, то нужно парсить post-данные руками.

Это сообщение отредактировал(а) cruelangel - 2.10.2007, 13:12
PM MAIL   Вверх
smartov
Дата 2.10.2007, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


свой собственный
****


Профиль
Группа: Экс. модератор
Сообщений: 4225
Регистрация: 2.2.2006
Где: NJ

Репутация: 7
Всего: 259



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

Делал так.

Был "шаблон" того, что надо клонировать, с id-шками полей например name, surname, address и именами полей формата name="address[]" - то есть чтобы приходило массивом.
Типа такого
Код

<!-- template -->
<table id="template">
<tr>
    <td><input type="text" name="name[]" id="name" /></td>
</tr>
<tr>
    <td><input type="text" name="address[]" id="address" /></td>
</tr>
</table>


Все id нужных полей лежат в массиве например dynamicFields.
Так-же была переменка счетчик, для того чтобы новые id делать уникальными.
Код

var dynamicFields_types = new Array('text', 'text');
var dynamicFields_names = new Array('name', 'address');
var counter = 1;


Так же я написал (по быстрому) функцию поиска заданного child-a по имени тега и id
Код

/**
 * Возвращает ссылку на child-a ноды tparent  с именем тега tagName и заданным id
 *
 */
function getSubelementByTagAndId(tparent, tagName, id) {
    if (tparent == null)
        return;

    if (id == null || !id)
        return tparent.getElementsByTagName(tagName)[0];

    for (var i=0; tparent.getElementsByTagName(tagName)[i]; i++) {
        if (tparent.getElementsByTagName(tagName)[i].id == id)
            return tparent.getElementsByTagName(tagName)[i];
    }
    
    return null;
}


Когда надо было создать новую копию, я делал 
1) клон с "шаблона" (cloneNode и до поры не делал appendChild)
2) использовал getSubelementByTagAndId чтобы найти всех детей клона (благо список кого искать у нас в массиве)
3) заменял всем детям id с оригинального на id+'_'+counter (то есть получалось типа name_1 ...)
4) counter++

FAQ:
1) Почему не использовал getElementById думаю ясно - сразу после клонирования он будет возвращать неверный результат.
2) Почему функция getSubelementByTagAndId написана так, что требует еще тип тега - потому что внутри использует getElementsByTagName, можно переписать на пробег по всем child-aм самостоятельно, но это будет работать медленнее, зато не нужно будет передавать тип тега.

Добавлено @ 13:32
На счет перемешки.

Цитата(dm9 @  2.10.2007,  12:07 Найти цитируемый пост)
А вперемешку -- это как? Клонируемые ноды должны по вёрстке располагаться одна под другой. 


Я так понимаю товарищ предлагает склонировать ноду используя cloneNode а дальше не искать child-ов, а сделать replace в innerHTML нужных подстрок.
Лично я считаю такой вариант опасным, потому что можно ненароком что-то забыть и заменяться будет не то, что нужно

Это сообщение отредактировал(а) smartov - 2.10.2007, 13:32
PM MAIL   Вверх
dsCode
Дата 2.10.2007, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



smartov, 
Цитата(smartov @  2.10.2007,  13:28 Найти цитируемый пост)
Я так понимаю товарищ предлагает склонировать ноду используя cloneNode а дальше не искать child-ов, а сделать replace в innerHTML нужных подстрок.
Лично я считаю такой вариант опасным, потому что можно ненароком что-то забыть и заменяться будет не то, что нужно

вполне, может быть и опасным (в конкретной реализации), я вообще отстраненно сказал, из расчета оптимизации по скорости. Создание элементов через DOM, на мой взгляд, тоже более красивое и удобо-редактируемое в дальнейшем. Но innerHTML будет работать быстрее (особенно, если его не конкатенатить (строку собирать), а писать сначала части в массив, а потом join('') сделать - самый быстрый вариант). Но DOM, повторю, мне кажется более гибким и в каких-то реализациях - более правильным даже (хоть он и медленней).


--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
Се ля ви
Дата 2.10.2007, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java/SOAрхитектор
****


Профиль
Группа: Модератор
Сообщений: 2016
Регистрация: 5.6.2004
Где: place without tim e and space

Репутация: 5
Всего: 127



Второй. Думаю, камней особых не будет, если грамотно написать - но в тебе я не сомневаюсь smile

Добавлено через 7 минут и 19 секунд
Вот! Как раз как smartov советует smile


--------------------
  )
 (
[_])
проф. блог

Кролики думали, что занимаются любовью, а на самом деле их просто разводили...
PM MAIL WWW Skype GTalk   Вверх
dm9
Дата 4.10.2007, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дмитрий Копытин
****


Профиль
Группа: Vingrad developer
Сообщений: 3876
Регистрация: 22.7.2002
Где: Москва

Репутация: нет
Всего: 137



smartov, спасибо большое.
Попробую сделать именно так.

Меня больше всего смущало как раз (временное) наличие одинаковых идентификаторов. А это нигде ошибок в консоль не бросает?

PM MAIL ICQ   Вверх
smartov
Дата 4.10.2007, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


свой собственный
****


Профиль
Группа: Экс. модератор
Сообщений: 4225
Регистрация: 2.2.2006
Где: NJ

Репутация: 7
Всего: 259



dm9, 
Цитата(dm9 @  4.10.2007,  15:08 Найти цитируемый пост)
А это нигде ошибок в консоль не бросает?

Попробуй - узнаешь smile Совсем девелоперы обленились smile
У меня не бросало. Потому что в этом ничего такого нет. Можешь попробовать сделать просто страничку с двумя элементами с одинаковым id и проверить что будет. Чаще всего просто ничего не вернется по getElementById, в остальном от браузера зависит - undefined behavior в общем, но не ошибка.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0585 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.