Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Замена элемента со всеми потрохами (https://javascript.ru/forum/events/4464-zamena-ehlementa-so-vsemi-potrokhami.html)

Diem 23.07.2009 19:48

Замена элемента со всеми потрохами
 
Есть ли универсальный способ заменить существующий DOM элемент, вместе с самим тегом и параметрами по аналогии с replaceChild(), но без предварительного создания средствами document.createElement(), то есть новый эелемент перед заменой имеется только в виде текстовой переменной (html).

спасибо.

Diem 23.07.2009 22:02

Пока только вот такое в голову пришло.

function replace_element_by_html(target, html)
{
    var tmpNode = document.createElement('div');
    tmpNode.innerHTML = html;
    
    for (key in tmpNode.childNodes)
    {
        target.parentNode.insertBefore(tmpNode.childNodes[key].cloneNode(true), target);
    }
    
    target.parentNode.removeChild(target);
}


Не очень конечно с точки зрения производительности.

B~Vladi 24.07.2009 09:51

Попробуй так:
function replace_element_by_html(ele, html){
    var newEle=ele.cloneNode(false);
    newEle.innerHTML=html;
    ele.parentNode.insertBefore(newEle, ele);
    ele.parentNode.removeChild(ele);
}

Riim 24.07.2009 10:24

Цитата:

Сообщение от B~Vladi
Попробуй так:

Один тег (newEle) лишний будет.

B~Vladi 24.07.2009 10:25

Цитата:

Сообщение от Riim
Один тег (newEle) лишний будет.

Что то не соображу... Как по-другому записать?!

Riim 24.07.2009 10:34

Цитата:

Сообщение от B~Vladi
Что то не соображу... Как по-другому записать?!

Вместо ele.parentNode.insertBefore(newEle, ele);
переписывать не newEle, а в цикле все его содержимое.
Но это все равно противоречит ТС:
Цитата:

без предварительного создания средствами document.createElement()
cloneNode, createDocumentFragment и прочие это все тот же createElement (ну почти).

Diem 24.07.2009 11:36

Цитата:

Сообщение от B~Vladi (Сообщение 25248)
Попробуй так:
function replace_element_by_html(ele, html){
    var newEle=ele.cloneNode(false);
    newEle.innerHTML=html;
    ele.parentNode.insertBefore(newEle, ele);
    ele.parentNode.removeChild(ele);
}

В вашем примере будет обновленно только сожержимое ele, сам тег с параметрами останется прежним.
Всё же неважно, решение найденно.

Можно также делать cloneNode родительского элемента и манипулировать с ним, но в некоторых случаях это будет накладнее по ресурсам.

P.S. такой вопрос:
может существует стандартная функция которая переводит html в коллекцию элементов, никто не в курсе ?

Kolyaj 24.07.2009 11:51

Цитата:

Сообщение от Diem
может существует стандартная функция которая переводит html в коллекцию элементов, никто не в курсе ?

Стандартной не существует, но можно во фреймворках посмотреть реализацию.

Pattern 24.07.2009 14:44

Цитата:

Сообщение от Diem (Сообщение 25261)
может существует стандартная функция которая переводит html в коллекцию элементов, никто не в курсе ?

есть стандартное и доступное каждому решение, которое вы сами написали выше, и которое указали вам другие
function html2hodes(h){
var newEl=document.createElement('span');
newEl.innerHTML=h;
return newEl.childNodes;
}

Однако я голову уже сломал размышляя, почему нельзя использовать createElement? Что в нём такого запретного?

x-yuri 25.07.2009 23:48

Цитата:

Сообщение от Pattern
Однако я голову уже сломал размышляя, почему нельзя использовать createElement? Что в нём такого запретного?

оставь в покое свою голову, не на все вопросы стоит искать ответ ;)

по теме можно еще DocumentFragment попробовать заюзать

Diem 29.07.2009 21:03

document.createElement() можно и нужно! юзать. Но есть ситуации, когда этот метод не подходит, например если html получаешь ajax-ом.

document.createDocumentFragment() можно использовать в цикле затусовав туда все элементы, а потом один раз replaceChild, вместо множественных insertBefore;

function replace(targetNode, html)
    {
        var tmpNode = document.createElement('div');
        tmpNode.innerHTML = html;
        
        var fragmentNode = document.createDocumentFragment();
        while (tmpNode.firstChild) {
            fragmentNode.appendChild(tmpNode.firstChild);
        }
        
        targetNode.parentNode.replaceChild(fragmentNode, targetNode);
    }


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