Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Работа с HTML до его вставки в дерево DOM


Автор: WIPS 15.6.2009, 13:24
Суть вопроса.

Допустим, что от аякса (не важно откуда) пришел HTML, он содержится как строка в переменной. Теперь нам этот HTML нужно вставить в дерево элементов, чтобы он пропарсился и все такое, делаем так:
Код

// переменная, где у нас HTML
var html_string;
document.getElementById('some_container').innerHTML = html_string;

Вопрос в том, можно ли как-то менять этот HTML средствами DOM (а не парсиньем строки), до того как мы включим его в дерево элементов документа, т.е. как-то так (ф-ции выдуманные, не пинать!):
Код

// переменная, где у нас HTML
var html_string;
// создаем из строки дерево элементов
var sub_document = createDocument(html_string);
// в нашем альтернативном дереве производим какие-то действия с помощью DOM (не важно какие)
sub_document.getElementById('some_element').style.color = '#123456';
sub_document.getElementById('some_element2').style.color = '#654321';
// измененный DOM снова вставляем в переменную
var html_sting = sub_document.toString();
// вставляем наш измененный HTML
document.getElementById('some_container').innerHTML = html_string;
// ощущаем счастье и удовлетворенность :)

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

Автор: Astraller 15.6.2009, 13:34
Возможно извращение, но почему не так:
Код

// переменная, где у нас HTML
var html_string;
// создаем из строки дерево элементов
var sub_document = document.createElement("span");
sub_document.innerHTML = html_string;
// в нашем альтернативном дереве производим какие-то действия с помощью DOM (не важно какие)
sub_document.childNodes[0].style.color = '#123456';
sub_document.childNodes[0].style.color = '#654321';
// вставляем наш измененный DOM
document.getElementById('some_container').appendChild(sub_document);
// ощущаем счастье и удовлетворенность :)

Автор: WIPS 15.6.2009, 14:20
В такой ситуации во время 
Код

var sub_document = document.createElement("span");
sub_document.innerHTML = html_string;

элемент span и наша строка уже вставляется в дерево DOM, а мне надо перед этим произвести манипуляции...

Автор: Astraller 15.6.2009, 14:33
Я думал суть в изменении не до фактического вставления в DOM, а в изменении до того как увидит пользователь... я ошибался? 

Автор: Aliance 15.6.2009, 15:13
А почему бы это не сделать после добавления в документ? Ведь DOM работает с узлами, а не со строками.

Автор: WIPS 15.6.2009, 16:58
Цитата(Astraller @  15.6.2009,  13:33 Найти цитируемый пост)
Я думал суть в изменении не до фактического вставления в DOM, а в изменении до того как увидит пользователь... я ошибался?  

Суть именно в том, чтобы изменить до вставки. Камень предкновения не в отображении.

Цитата(Aliance @  15.6.2009,  14:13 Найти цитируемый пост)
А почему бы это не сделать после добавления в документ? Ведь DOM работает с узлами, а не со строками. 

Мне не надо со строками. Я хочу работать именно с узлами. Но эти узлы должны быть не в текущем документе. Например мне придут элементы с id, кот. уже есть в текущем документе, мне нужно будет повыбирать те, кот. еще нет в моем документе и потом их повставлять в него (это для примера, не нужно цепляться именно к id, мне просто нужен способ работать с деревом DOM, но не в текущем документе).

Кстати, как оказалось параллельно альтернативный документ создать нельзя :(
Код

var my_doc = new Document(); // такая конструкция не работает... жаль

Автор: Astraller 15.6.2009, 17:21
Ээээ, в действительности можно попробовать соорудить скрытый фрейм, в который поместить полученный HTML. Таким образом вы получите "экземпляр странице в пробирке". С которым можно делать все что угодно.

Автор: bazzjr 15.6.2009, 17:50
Не понял для какой целы нужны данные манипуляции, да и вообще правильный ли подход к решению проблеммы...

Автор: ksnk 15.6.2009, 19:30
Вообще-то document.createElement(...)+ innerHTML=... никуда никакой элемент не вставляют. И getElementById свежесостряпанную веточку найти не смогут до его реальной вставки в дерево.

Автор: WIPS 15.6.2009, 21:25
Цитата(Astraller @  15.6.2009,  13:33 Найти цитируемый пост)
в действительности можно попробовать соорудить скрытый фрейм  

Да я тоже об этом думал. Но фрейм как-то громоздко smile

Цитата(bazzjr @  15.6.2009,  16:50 Найти цитируемый пост)
Не понял для какой целы нужны данные манипуляции, да и вообще правильный ли подход к решению проблеммы...

Цель - мировое господство smile только я Вам этого не говорил ;) Суть не в подходе. Задача решена. Тут уже академический интерес.

Цитата(ksnk @  15.6.2009,  18:30 Найти цитируемый пост)
Вообще-то document.createElement(...)+ innerHTML=... никуда никакой элемент не вставляют. 

Хм... а что же тогда происходит? Поподробнее пожаста, если Вас не затруднит.

Цитата(ksnk @  15.6.2009,  18:30 Найти цитируемый пост)
И getElementById свежесостряпанную веточку найти не смогут до его реальной вставки в дерево. 

А в какой момент происходит "реальная" вставка. На element.show()? Тоже хотелось бы поподробнее.

Автор: Astraller 15.6.2009, 21:28
Цитата(WIPS @  15.6.2009,  21:25 Найти цитируемый пост)
А в какой момент происходит "реальная" вставка. На element.show()? Тоже хотелось бы поподробнее.

Как я понимаю, в момент appendChild'а smile

Автор: ksnk 15.6.2009, 22:24
Цитата(WIPS @  15.6.2009,  21:25 Найти цитируемый пост)
А в какой момент происходит "реальная" вставка. На element.show()? Тоже хотелось бы поподробнее.

Код

<div id="container"></div>
<script>

var $x=[];

$x.push('at start');$x.push(document.getElementById('xxx'));

var el=document.createElement('div');
el.innerHTML='<div id="xxx">Hello! world</div>';

$x.push('after creation');$x.push(document.getElementById('xxx'));

document.getElementById('container').appendChild(el);

$x.push('after insertion');$x.push(document.getElementById('xxx'));

alert($x);
</script>

Автор: youri 15.6.2009, 23:24
Цитата(WIPS @  15.6.2009,  16:58 Найти цитируемый пост)
Например мне придут элементы с id, кот. уже есть в текущем документе, мне нужно будет повыбирать те, кот. еще нет в моем документе и потом их повставлять в него

с этой проблемой вроде разобрались, что еще не так?

Цитата(WIPS @  15.6.2009,  16:58 Найти цитируемый пост)
Кстати, как оказалось параллельно альтернативный документ создать нельзя

можно, но не нужно

Цитата(WIPS @  15.6.2009,  21:25 Найти цитируемый пост)
Суть не в подходе

а в чем же, как не в нем? Или ты предпочитаешь решать проблемы так, как в голову всбредет, а не выбирать лучший в данной ситуации (нормальный) подход?

Автор: WIPS 16.6.2009, 10:00
Цитата(youri @  15.6.2009,  22:24 Найти цитируемый пост)
Цитата(WIPS @  15.6.2009,  16:58 )
Например мне придут элементы с id, кот. уже есть в текущем документе, мне нужно будет повыбирать те, кот. еще нет в моем документе и потом их повставлять в него

с этой проблемой вроде разобрались, что еще не так?

интересно как это Вы разбираетесь с одинаковыми id?

Цитата(youri @  15.6.2009,  22:24 Найти цитируемый пост)
Цитата(WIPS @  15.6.2009,  16:58 )
Кстати, как оказалось параллельно альтернативный документ создать нельзя

можно, но не нужно

я сам решу нужно ли мне создавать альтернативный документ, а вот если Вы знаете как это сделать, то милости прошу - поведайте

Цитата(youri @  15.6.2009,  22:24 Найти цитируемый пост)
Цитата(WIPS @  15.6.2009,  21:25 )
Суть не в подходе

а в чем же, как не в нем? Или ты предпочитаешь решать проблемы так, как в голову всбредет, а не выбирать лучший в данной ситуации (нормальный) подход?

я предпочитаю решать проблему оптимальным способом, и если бы Вы были внимательнее, то увидели бы выше, что проблема уже решена, или словосочетание "академический интерес" Вам не понятно?

Цитата(Astraller @  15.6.2009,  20:28 Найти цитируемый пост)
Как я понимаю, в момент appendChild'а

Судя по эксперименту ksnk так и есть.

ksnk, спасибо Вам за точный пример по теме! 

Но повторюсь, что чисто в образовательных целях было бы интересно, можно ли как-то сделать операцию аналогичную такой:
Код

var el = document.createElement('div');
el.innerHTML = '<div id="xxx">Hello! world</div>';
alert(el.getChildById('xxx'));

Автор: Astraller 16.6.2009, 10:16
Цитата(WIPS @  16.6.2009,  10:00 Найти цитируемый пост)
Но повторюсь, что чисто в образовательных целях было бы интересно, можно ли как-то сделать операцию аналогичную такой:

А в чем проблема то:
Код

function getChildById(id){
  for(i=0;this.childNodes[i];i++){
    if (this.childNodes[i].getAttribute('id') == id){
      return this.childNodes[i];
    }
  }
  return false;
}

Автор: ksnk 16.6.2009, 10:34
Astraller, а если вставлено ветвистое дерево?  smile 

Автор: Astraller 16.6.2009, 10:51
Цитата(ksnk @  16.6.2009,  10:34 Найти цитируемый пост)
а если вставлено ветвистое дерево? 

Ваша правда, не учел:
Код

function getChildById(id){
  for(i=0;this.childNodes[i];i++){
    if (this.childNodes[i].getAttribute('id') == id){
      return this.childNodes[i];
    }
    if(this.childNodes[i].childNodes.length > 0){
      if (this.childNodes[i].getChildById(id) != false){
        return this.childNodes[i].getChildById(id);
      }
    }
  }
  return false;
}

Автор: WIPS 16.6.2009, 10:58
Эх, не успел... у меня такое вышло: 
Код

<html>
    <body>
        <script>
            Object.prototype.getChildById = function (id) {
                if ((this.getAttribute && this.getAttribute('id') == id) || (this.id && this.id == id)) {
                    return this;
                } else {
                    for (i = 0; this.childNodes[i]; i++) {
                        var obj = this.childNodes[i].getChildById(id);
                        if (obj) {
                            return obj;
                        }
                    }
                    return false;
                }
            }

            var el = document.createElement('div');
            el.innerHTML = '<div id="xxx">Hello! <span id="yyy">world</span></div>';

            alert(el.getChildById('yyy'));
        </script>
    </body>
</html>

вобщем я добавил функу в прототип, чтобы работало "нативнее".

Вот так ненавящиво мы и подошли к решению вопроса. Таки можно по дереву побегать не вставляя его в основное дерево документа. Всем спасибо.

Автор: Astraller 16.6.2009, 11:02
Цитата(WIPS @  16.6.2009,  10:58 Найти цитируемый пост)
у меня такое вышло 

id лучше получать по getAttribute ибо до вставки в DOM приколы могут быть самые разные  smile 

Автор: WIPS 16.6.2009, 11:08
Цитата(Astraller @  16.6.2009,  10:02 Найти цитируемый пост)
id лучше получать по getAttribute ибо до вставки в DOM приколы могут быть самые разные

согласен, исправил

Автор: youri 16.6.2009, 13:33
Цитата(WIPS @  16.6.2009,  10:00 Найти цитируемый пост)
с этой проблемой вроде разобрались, что еще не так?

интересно как это Вы разбираетесь с одинаковыми id?

я с ней не разбирась, вы с ней разобрались, благодаря ksnk

Цитата(WIPS @  16.6.2009,  10:00 Найти цитируемый пост)
я сам решу нужно ли мне создавать альтернативный документ, а вот если Вы знаете как это сделать, то милости прошу - поведайте

ну раз сами решите, то сами и решайте, как это сделать ;)

Цитата(WIPS @  16.6.2009,  10:00 Найти цитируемый пост)
я предпочитаю решать проблему оптимальным способом, и если бы Вы были внимательнее, то увидели бы выше, что проблема уже решена, или словосочетание "академический интерес" Вам не понятно?

какая разница: есть/была проблема, но нету контекста.  Или вы решаете проблемы универсально, вне зависимости от контекста?

Автор: WIPS 16.6.2009, 14:25
youri, спасибо за Ваше мнение, оно очень важно для нас ;) Тема закрыта.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)