1. JavaScript / Говнокод #11898

    +157

    1. 1
    2. 2
    3. 3
    4. 4
    var body=document.getElementsByTagName('body')[0];
    var newBody="";
    newBody='<div id="'+this.cntID+'" class="hide you">'+this.flashCntDivArr.join('')+'</div>'+bgLayerDiv+"<div id='tplCnt'>"+body.innerHTML+"</div>";
    body.innerHTML=newBody;

    Натолкнулся в одном из проектов на такой вот способ добавления элемента в DOM. Я чего-то не понимаю?

    Запостил: nbspjr, 09 Октября 2012

    Комментарии (11) RSS

    • Ну, так, по крайней мере короче, чем 100500 раз document.appendChild( document.createElement() ) писать.
      Ответить
      • Извиняюсь, я мал-мало вырвал код из контекста. Этот конкретный пример делает вот что: выводит сообщение об ошибке в заголовок страницы, если флеш не установлен, а текущий контент body оборачивает в див, чтобы страница не развалилась...

        Если же флеш установлен, происходит такое:
        newBody='<div id="'+this.cntID+'" class="hide you">'+this.flashCntDivArr.join('')+'</div>'+bgLayerDiv+body.innerHTML;

        Соответственно, весь флеш на странице в это время перезагружается. Добавление этого div происходит только один раз.
        Ответить
        • Если флеш, да и вообще любой другой элемент на странице нужно переставить в другой контейнер - все равно перезагрузится. Браузеры не умеют кешировать элементы DOM и тупо пересоздают их по-новой каждый раз как их перемещают с места на место. По этой самой причине, например, всякие SVG рисовалки обречены - им никогда не удастся манипулировать большим количеством элементов, и т.п.
          Наверное, просто не нужно было грузить флеш изначально, а только после проверки.
          Ответить
          • А в этом случае ничто никуда не переставляется. На страничке есть флеш - он сам по себе. По нажатию на кнопку единожды вставляется таким вот образом div, в который добавляется флеш-галерея, и выводится в оверлее. Соответственно, весь контент передергивается и весь флеш на странице перезагружается.

            Но если флеш плагин не подключен, то происходит то, что запощено в говнокоде: весь контент на странице оборачивается в div, а перед контентом вставляется div с сообщением об ошибке.
            Ответить
    • в одну строчку не проще?
      document.getElementsByTagName('body')[0].innerHTML='<div id="'+this.cntID+'" cla...
      Ответить
    • Меня так раздражает dom api, что я написал свой велик вроде этого http://ideone.com/9BnsZ
      Только экранирования нет, оно мне не нужно было. Работает примерно так:
      tmpl.render(['div', {'class': 'test'}, ['a', {'href': 'http://lol'}]])
      Ответить
      • А. Так я не один такой. Причем у меня структура точь-в-точь: (element_name, map of attrs, optional array of inner elements)
        У резига кстати похожий шаблонизатор был.
        Ответить
      • А не. У резига херня какая-то. И в jQuery тоже неудобно - надо писать
        $('<'+name+'/>',{attrs}).append(inner).
        Но всё-равно уверен, что такую байду писали многие js-кодеры изнуренные document.createElementами.

        Ром, а у тебя оно тоже работает в том случае когда второй аргумент - массив вложенных, а не мап?
        Ответить
        • > у тебя оно тоже работает в том случае когда второй аргумент - массив вложенных, а не мап?
          Да, ещё можно функции подставлять, которые генерят спецификации, вроде такого:
          tmpl.render(['ul', function () {
                              var items = [];
                              for (var i = 1; i <= 10; ++i) {
                                  items.push(['li', String(i)]);
                              }
                              return items;
                          }]);
          Ответить
          • Ну до функций я не дошёл - такое обычно не требовалось. короче вот мой лесик, который вызывается из метода создания объекта:
            // container - элемент
            //args - аргументы
            //n - суть та же что и у тебя, сдвиг в массиве когда начинаются вложенные элементы.
            appendArgList:function(container,args,n)
            {
            	var _len=args.length;
            	if (_len>n)
            		for (var _i=n; _i < _len;++_i)
            		{
            			var _inner=args[_i];
            			if ( _inner){
            				if (   _inner instanceof jQuery 
            					|| _inner instanceof String 
            					|| _inner.constructor.name=='String'
            					) 
            					container.append.apply( container,[_inner]);
            				else if (_inner instanceof Array){ 
            					container.append.apply( container,_inner);
            				}
            				else throw "Error when appending"+_i;
            			}			
            		}	
            	return container;
            }
            Ответить
    • Ясно, мне еще учиться и учиться :) Но добавлять элемент в DOM таким образом, как я описал - все равно извращение. Особенно если на странице присутствует флеш, который перезагружается при каждом нажатии на кнопку.
      Ответить

    Добавить комментарий