0,0
рейтинг
23 января 2014 в 14:01

Разработка → Web Components — будущее Web из песочницы

Спустя какое время стало ясно, что основная идея Prototype вошла в противоречие с миром. Создатели браузеров ответили на возрождение Javascript добавлением новых API, многие из которых конфликтовали с реализацией Prototype.

— Sam Stephenson, создатель Prototype.js, You Are Not Your Code

Создатели браузеров поступают гармонично. Решение о новых API принимают с учётом текущих трендов в opensource сообществах. Так prototype.js способствовал появлению Array.prototype.forEach(), map() и т.д., jquery вдохновил разработчиков на HTMLElement.prototype.querySelector() и querySelectorAll().

Код на стороне клиента становится сложнее и объёмнее. Появляются многочисленные фреймворки, которые помогают держать этот хаос под контролем. Backbone, ember, angular и другие создали, чтобы помочь писать чистый, модульный код. Фреймворки уровня приложения — это тренд. Его дух присутствует в JS среде уже какое-то время. Не удивительно, что создатели браузеров решили обратить на него внимание.

Web Components — это черновик набора стандартов. Его предложили и активно продвигают ребята из Google, но инициативу уже поддержали в Mozilla. И Microsoft. Шучу, Microsoft вообще не при делах. Мнения в комьюнити противоречивые (судя по комментариям, статьям и т.д.).

Основная идея в том, чтобы позволить программистам создавать “виджеты”. Фрагменты приложения, которые изолированы от документа, в который они встраиваются. Использовать виджет возможно как с помощью HTML, так и с помощью JS API.

Я пару недель игрался с новыми API и уверен, что в каком-то виде, рано или поздно эти возможности будут в браузерах. Хотя их реализация в Chrome Canary иногда ставила меня в тупик (меня, и сам Chrome Canary), Web Components кажется тем инструментом, которого мне не хватало.

Стандарт Web Components состоит из следующих частей:

  • Templates

    Фрагменты HTML, которые программист собирается использовать в будущем.

    Содержимое тегов <template> парсится браузером, но не вызывает выполнение скриптов и загрузку дополнительных ресурсов (изображений, аудио…) пока мы не вставим его в документ.

  • Shadow DOM

    Инструмент инкапсуляции HTML.

    Shadow DOM позволяет изменять внутреннее представление HTML элементов, оставляя внешнее представление неизменным. Отличный пример — элементы <audio> и <video>. В коде мы размещаем один тег, а браузер отображает несколько элементов (слайдеры, кнопки, окно проигрывателя). В Chrome эти и некоторые другие элементы используют
    Shadow DOM.

  • Custom Elements

    Custom Elements позволяют создавать и определять API собственных HTML элементов. Когда-нибудь мечтали о том, чтобы в HTML был тег <menu> или <user-info>?

  • Imports

    Импорт фрагментов разметки из других файлов.

В Web Components больше частей и маленьких деталей. Некоторые я ещё буду упоминать, до каких-то пока не добрался.

Templates


Концепция шаблонов проста. Хотя под этим словом в стандарте подразумевается не то, к чему мы привыкли.

В современных web-фреймворках шаблоны — это строки или фрагменты DOM, в которые мы подставляем данные перед тем как показать пользователю.

В web components шаблоны — это фрагменты DOM. Браузер парсит их содержимое, но не выполняет до тех пор, пока мы не вставим его в документ. То есть браузер не будет загружать картинки, аудио и видео, не будет выполнять скрипты.

К примеру, такой фрагмент разметки в документе не вызовет загрузку изображения.

      <template id="tmpl-user">
        <h2 class="name">Иван Иваныч</h2>
        <img src="photo.jpg">
      </template>

Хотя браузер распарсит содержимое <template>. Добраться до него можно с помощью js:

    var tmpl = document.querySelector('#tmpl-user');
    // содержимое <template>
    var content = tmpl.content;
    var imported;

    // Подставляю данные в шаблон:
    content.querySelector('.name').innerText = 'Акакий';

    // Чтобы скопировать содержимое и сделать его частью документа,
    // используйте document.importNode()
    //
    // Это заставит браузер `выполнить` содержимое шаблона,
    // в данном случае начнёт грузится картинка `photo.jpg`
    imported = document.importNode(content);

    // Результат импорта вставляю в документ:
    document.body.appendChild(imported);


Пример работы шаблонов можно посмотреть здесь.

Все примеры в статье следует смотреть в Chrome Canary со включенными флагами:

  • Experimental Web Platform features
  • Enable HTML Imports
  • Enable Experimental Javascript


Для Чего?


На данный момент существует три способа работы с шаблонами:

  1. Добавить шаблон в скрытый элемент на странице. Когда он будет нужен,
    скопировать и подставить данные:

            <div hidden data-template="my-template">
              <p>Template Content</p>
              <img></img>
            </div>
    

    Минусы такого подхода в том, что браузер попытается “выполнить” код шаблона. То есть загрузить картинки, выполнить код скриптов и т.д.

  2. Получать содержимое шаблона в виде строки (запросить AJAXом или из <script type="x-template">).

             <sctipt type="x-template" data-template="my-template">
               <p>Template Content</p>
               <img src="{{ image }}"></img>
             </script>
    

    Минус в том, что приходится работать со строками. Это создаёт угрозу XSS, нужно уделять дополнительное внимание экранированию.

  3. Компилируемые шаблоны, вроде hogan.js, также работают со строками. Значит имеют тот же изъян, что и шаблоны второго типа.


У <template> нет этих недостатков. Мы работаем с DOM, не со строками. Когда выполнять код, также решать нам.

Shadow DOM


Инкапсуляция. Этого в работе с разметкой мне не хватало больше всего. Что такое Shadow DOM и как он работает проще понять на примере.

Когда мы используем html5 элемент <audio> код выглядит примерно так:

    <audio controls src="kings-speech.wav"></audio>


Но на странице это выглядит так:

audio element

Мы видим множество контролов, прогресбар, индикатор длины аудио. Откуда эти элементы и как до них добраться? Ответ — они находятся в Shadow Tree элемента. Мы можем даже увидеть их в DevTools, если захотим.

Чтобы Chrome в DevTools отображал содержимое Shadow DOM, в настройках DevTools, вкладка General, раздел Elements ставим галочку Show Shadow DOM.

Содержимое Shadow DOM тега <audio> в DevTools:

devtools shadow dom

ссылка на пример

Теория Shadow DOM

Shadow Tree — это поддерево, которое прикреплено к элементу в документе. Элемент в этом случае называется shadow host, на его месте браузер показывает содержимое shadow tree, игнорируя содержимое самого элемента.

Именно это происходит с <audio> тегом в примере выше, на его месте браузер рендерит содержимое shadow tree.

Фишка shadow dom в том, что стили, определённые в нём с помощью <style>, не распространяются на родительский документ. Также у нас есть возможность ограничить влияние стилей родительского документа на содержимое shadow tree. Об этом позже.

Посадить теневое дерево

Shadow DOM API позволяет пользователям самостоятельно создавать и
манипулировать содержимым shadow tree.

пример
    <div class="shadow-host">
      Этот текст пользователь не увидит.
    </div>

    <script>
      var shadowHost = document.querySelector('.shadow-host');
      var shadowRoot = shadowHost.createShadowRoot();

      shadowRoot.innerText = 'Он увидит этот текст.'
    </script>

Результат:

custom shadow dom

ссылка на пример

Проекции, тег <content>


Проекция — это использование содержимого хоста в shadow tree. Для этого в стандарте есть тег <content>.

Важно, что <content> проецирует содержимое хоста, а не переносит его из хоста в shadow tree. Потомки хоста остаются на своём месте, на них распространяются стили документа (а не shadow tree). <content> это своего рода окно между мирами.

пример
    <template id="content-tag">
      <p>
        Это содержимое
        <strong>shadow tree</strong>.
      </p>
      <p>
        Ниже проекция содержимого
        <strong>shadow host</strong>:
      </p>
      <content></content>
    </template>

    <div class="shadow-host">
      <h1 class="name">Варлам</h1>
      <img src="varlam.png">
      <p class="description">Бодрый Пёс</p>
    </div>

    <script>
      var host = document.querySelector('.shadow-host'),
          template = document.querySelector('#content-tag'),
          shadow = host.createShadowRoot();

      shadow.appendChild(template.content);
    </script>

  

Результат:

content demo

ссылка на пример

Стили в Shadow DOM


Инкапсуляция стилей — основная фишка shadow DOM. Стили, которые определёны в shadow tree имеют силу только внутри этого дерева.

Досадная особенность — использовать в shadow tree внешние css файлы нельзя. Надеюсь, это поправят в будущем.

пример
    <template id="color-green">
      <style>
        div { background-color: green; }
      </style>

      <div>зелёный</div>
    </template>

    <div class="shadow-host"></div>

    <script>
      var host = document.querySelector('.shadow-host'),
      template = document.querySelector('#color-green'),
      shadow = host.createShadowRoot();

      shadow.appendChild(template.content);
    </script>

Зелёный фон в примере получит только `<div>` внутри shadow tree. То
есть стили «не вытекут» в основной документ.

Результат:

green

ссылка на пример

Наследуемые стили


По-умолчанию наследуемые стили, такие как color, font-size и другие, влияют на содержимое shadow tree. Мы избежим этого, если установим shadowRoot.resetStyleInheritance = true.

пример
    <template id="reset">
      <p>В этом примере шрифты сброшены.</p>

      <content></content>
    </template>

    <div class="shadow-host">
      <p>Host Content</p>
    </div>

    <script>
      var host = document.querySelector('.shadow-host'),
        template = document.querySelector('#reset'),
        shadow = host.createShadowRoot();

      shadow.resetStyleInheritance = true;
      shadow.appendChild(template.content);
    </script>

Результат:

inherit styles

ссылка на пример

Авторские стили


Чтобы стили документа влияли на то, как выглядит shadow tree, используйте свойство applyAuthorStyles.

пример
    <template id="no-author-st">
      <div class="border">div.border</div>
    </template>

    <style>
      /* В стилях документа */
      .border {
        border: 3px dashed red;
      }
    </style>

    <div class="shadow-host"></div>


    <script>
      var host = document.querySelector('.shadow-host'),
          template = document.querySelector('#no-author-st'),
          shadow = host.createShadowRoot();

      shadow.applyAuthorStyles = false; // значение по-умолчанию
      shadow.appendChild(template.content);
    </script>


Изменяя значение applyAuthorStyles, получаем разный результат:

applyAuthorStyles = false

no to author styles

applyAuthorStyles = true

yes to author styles

ссылка на пример, applyAuthorStyles=false

ссылка на пример, applyAuthorStyles=true

Селекторы ^ и ^^


Инкапсуляция это здорово, но если мы всё таки хотим добраться до shadow tree и изменить его представление из стилей документа, нам понадобится молоток. И кувалда.

Селектор div ^ p аналогичен div p с тем исключением, что он пересекает одну теневую границу (Shadow Boundary).

Селектор div ^^ p аналогичен предыдущему, но пересекает ЛЮБОЕ количество теневых границ.

пример
    <template id="hat">
      <p class="shadow-p">
        Это красный текст.
      </p>
    </template>

    <style>
      /* В стилях документа */
      .shadow-host ^ p.shadow-p {
        color: red;
      }
    </style>

    <div class="shadow-host"></div>

    <script>
      var host = document.querySelector('.shadow-host'),
      template = document.querySelector('#hat'),
      shadow = host.createShadowRoot();

      shadow.appendChild(template.content);
    </script>

Результат:

cat in the hat

ссылка на пример

Зачем нужен Shadow DOM?


Shadow DOM позволяет изменять внутреннее представление HTML элементов, оставляя внешнее представление неизменным.

Возможное применение — альтернатива iframe. Последний чересчур изолирован. Чтобы взаимодействовать с внешним документом, приходится изобретать безумные способы передачи сообщений. Изменение внешнего представления с помощью css просто невозможно.

В отличие от iframe, Shadow DOM — это часть вашего документа. И хотя shadow tree в некоторой степени изолировано, при желании мы можем изменить его представление с помощью стилей, или расковырять скриптом.

Custom Elements


Custom Elements — это инструмент создания своих HTML элементов. API этой части Web Components выглядит зрело и напоминает директивы
Angular
. В сочетании с Shadow DOM и шаблонами, кастомные элементы дают возможность создавать полноценные виджеты вроде <audio>, <video> или <input type="date">.

Чтобы избежать конфликтов, согласно стандарту, кастомные элементы должны содержать дефис в своём названии. По-умолчанию они наследуют HTMLElement. Таким образом, когда браузер натыкается на разметку вида <my-super-element>, он парсит его как HTMLElement. В случае <mysuperelement>, результат будет HTMLUnknownElement.

пример
    <dog></dog>
    <x-dog></x-dog>

    <dl>
      <dt>dog type</dt>
      <dd id="dog-type"></dd>
      <dt>x-dog type</dt>
      <dd id="x-dog-type"></dd>
    </dl>

    <script>
      var dog = document.querySelector('dog'),
          dogType = document.querySelector('#dog-type'),
          xDog = document.querySelector('x-dog'),
          xDogType = document.querySelector('#x-dog-type');

      dogType.innerText = Object.prototype.toString.apply(dog);
      xDogType.innerText = Object.prototype.toString.apply(xDog);
    </script>

Результат:

x-dog

ссылка на пример

API кастомного элемента


Мы можем определять свойства и методы у нашего элемента. Такие, как метод play() у элемента <audio>.

В жизненный цикл (lifecycle) элемента входит 4 события, на каждое мы можем повесить callback:

  • created — создан инстанс элемента
  • attached — элемент вставлен в DOM
  • detached — элемент удалён из DOM
  • attributeChanged — атрибут элемента добавлен, удалён или изменён

Алгоритм создания кастомного элемента выглядит так:

  1. Создаём прототип элемента.

    Прототип должен наследовать HTMLElement или его наследника,
    например HTMLButtonElement:

            var myElementProto = Object.create(HTMLElement.prototype, {
              // API элемента и его lifecycle callbacks
            });
    

  2. Регистрируем элемент в DOM с помощью document.registerElement():

            var myElement = document.registerElement('my-element', {
              prototype: myElementProto
            });
    


пример
    <x-cat></x-cat>
    <div>
      <strong>Cat's life:</strong>
      <pre id="cats-life"></pre>
    </div>

    <script>
      var life = document.querySelector('#cats-life'),
          xCatProto = Object.create(HTMLElement.prototype, {
            nickName: 'Cake', writable: true
          });

      xCatProto.meow = function () {
        life.innerText += this.nickName + ': meow\n';
      };

      xCatProto.createdCallback = function () {
        life.innerText += 'created\n';
      };

      xCatProto.attachedCallback = function () {
        life.innerText += 'attached\n';
      };

      xCatProto.detachedCallback = function () {
        life.innerText += 'detached\n';
      };

      xCatProto.attributeChangedCallback = function (name, oldVal, newVal) {
        life.innerText += (
          'Attribute ' + name +
          ' changed from ' + oldVal +
          ' to ' + newVal + '\n');
      };

      document.registerElement('x-cat', { prototype: xCatProto });

      document.querySelector('x-cat').setAttribute('friend', 'Fiona');

      document.querySelector('x-cat').meow();

      document.querySelector('x-cat').nickName = 'Caaaaake';
      document.querySelector('x-cat').meow();

      document.querySelector('x-cat').remove();
    </script>

Результат:

cats life

ссылка на пример

Зачем нужны Custom Elements?


Custom Elements это шаг к семантической разметке. Программистам важно создавать абстракции. Семантически-нейтральные <div> или <ul> хорошо подходят для низкоуровневой вёрстки, тогда как Custom Elements позволят писать модульный, удобочитаемый код на высоком уровне.

Shadow DOM и Custom Elements дают возможность создавать независимые от контекста виджеты, с удобным API и инкапсулированным внутренним представлением.

HTML Imports


Импорты — простое API, которому давно место в браузерах. Они дают возможность вставлять в документ фрагменты разметки из других файлов.

пример
    <link rel="import" href="widget.html">

    <sctipt>
      var link = document.querySelector('link[rel="import"]');

      // Доступ к импортированному документу происходит с помощью свойства
      // *import*.
      var importedContent = link.import;

      importedContent.querySelector('article');
    </sctipt>


Object.observe()


Ещё одно приятное дополнение и часть Web Components (кажется), это API для отслеживания изменений объекта Object.observe().

Этот метод доступен в Chrome, если включить флаг Experimental Web Platform features.

пример
    var o = {};

    Object.observe(o, function (changes) {
      changes.forEach(function (change) {

        // change.object содержит изменённую версию объекта

        console.log('property:', change.name, 'type:', change.type);
      });
    });

    o.x = 1     // property: x type: add
    o.x = 2     // property: x type: update
    delete o.x  // property: x type: delete

При изменении объекта o вызывается callback, в него передаётся массив
свойств, которые изменились.

TODO widget


Согласно древней традиции, вооружившись этими знаниями, я решил сделать простой TODO-виджет. В нём используются части Web Components, о которых я рассказывал в статье.

Добавление виджета на страницу сводится к одному импорту и одному тегу в теле документа.

пример
    <html>
      <head>
        <link rel="import" href="todo.html">
      </head>
      <body>
        <x-todo></x-todo>
      </body>
    </html>

    <script>
      // JS API виджета:
      var xTodo = document.querySelector('x-todo');
      xTodo.items();                // список задач
      xTodo.addItem(taskText);      // добавить
      xTodo.removeItem(taskIndex);  // удалить
    </script>


Результат:

todo widget

ссылка на демо

Заключение


С развитием html5 браузеры стали нативно поддерживать новые медиа-форматы. Также появились элементы вроде <canvas>. Теперь у нас огромное количество возможностей для создания интерактивных приложений на клиенте. Этот стандарт также представил элементы <article>, <header>, и другие. Разметка стала “иметь смысл”, приобрела семантику.

На мой взгляд, Web Components — это следующий шаг. Разработчики смогут создавать интерактивные виджеты. Их легко поддерживать, переиспользовать, интегрировать.

Код страницы не будет выглядеть как набор “блоков”, “параграфов” и “списков”. Мы сможем использовать элементы вроде “меню”, “новостная лента”, “чат”.

Конечно, стандарт сыроват. К примеру, импорты работают не так хорошо, как шаблоны. Их использование рушило Chrome время от времени. Но объём нововведений поражает. Даже часть этих возможностей способна облегчить жизнь web-разработчикам. А некоторые заметно ускорят работу существующих фреймворков.

Некоторые части Web Components можно использовать уже сейчас с помощью полифилов. Polymer Project — это полноценный фреймворк уровня приложения, который использует Web Components.

ƒ

Ссылки




Eric Bidelman, серия статей и видео о Web Components:

Андрей Саломатин @filipovskii_off
карма
49,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (89)

  • +4
    Я уже читал несколько статей про эти предлагаемые нововведения. Один момент мне непонятен, почему это называют веб-компонентами? Именно компонентами? С точки браузера это вроде бы не компоненты. Я в статьях не вижу такого, что бы компонент был создан один раз и использовался в нескольких местах. Там везде рисуют создание нового теневого дерева и его элементов при каждом использовании. То есть это теплейтинг поддерживаемый непосредственно в браузере. Правильно я понимаю или что-то упустил?
    • 0
      Могу только догадываться почему назвали именно так. В источниках эта информация не попадалась.

      В примерах к этой статье, например здесь (код) и тут (код) я переиспользую самописный элемент <wc-example>, его код лежит здесь.

      Получившийся TODO-виджет также можно переиспользовать. Импортим html-файл на страницу, и браузер будет рисовать виджет на месте <x-todo> элементов.

      Тег <template> это не совсем темплейтинг. Скорее механизм отложить фрагмненты разметки, пока они не пригодятся. Подставлять данные в содержимое <template> нужно вручную, с помощью js.
      • +1
        Но он же не переиспользует общий компонент, а каждый раз создает новые фрагменты документа по указанному образцу. И когда создает фрагмент, получившийся фрагмент не как отдельная сущность, а как набор элементов в дереве элементов документа. Что именно в этом от понятия «компонент»? Мне кажется это типичный шаблон.
        • +1
          Я думаю, под компонентом здесь понимается часть общей системы web разработки на стороне клиента, а не то как вы этот компонент применяете. Если говорить с точки зрения повторяющейся логики, то это относится к возможности создания своих компонентов, а здесь описано именно их применение.

          Простейший пример — тег template — это компонент для создания шаблонов, как если бы в каком-нибудь веб-фреймворке компонент system.template отвечал бы за базовый функционал создания template на стороне сервера / клиента.
        • 0
          Всё верно, он каждый раз создаёт новые фрагменты документа. Но в отличие от шаблона, shadow tree изолировано от остального DOM, то есть:

          • Добраться до содержимого shadow tree с помощью document.querySelector() и querySelectorAll() нельзя
          • Стили, определённые в документе не распространяются на содержимое (если applyAuthorStyles = false)
          • Стили, определённые в shadow tree не распространяются на документ.

          Наружу у «кастомного элемента» торчит только JS API, определённое разработчиком.
  • 0
    Они дают возможность вставлять в документ фрагменты разметки из других файлов.

    Импортируемый документ должен быть нормальным html-документом (доктайп, html, head, body и т. п.) или действительно фрагментом html, включая неразмеченный текст? И происходит ли реимпорт при изменении атрибута href из JS?

    P.S. сейчас проверить нет возможности.
    • +1
      Импортируемый документ не должен быть полноценным. Это действительно фрагменты разметки. Импортируемый файл TODO-виджета, например, выглядит так.

      Реимпорт не происходит. Полагаю, это один из багов. Импорты работают не так хорошо, как всё остальное.
  • +1
    Читая статьи про Web Components, ощущаю стойкое Déjà Vu. У Adobe Flex как раз очень стройная компонентная модель. Там можно создавать свои элементы UI, которые можно добавлять в приложение (через XML разметку или с помощью ActionScript кода) как обычные кнопки, табы, ссылки. При этом компонент во Flex-е может объявлять собственные XML атрибуты, CSS свойства и события. Доступно наследование таких виджетов. Есть механизм Skin-ов для отделения логики от внешних красивостей.
    Эх, жаль, что Flash теряет популярность :(
    • +6
      Shadow DOM — это калька с микрософтовских HTML Components и behaviors (2001 год). Вот это дежавю всем дежавю дежавю.
      • 0
        Вообще Microsoft поддерживала создание кастомных тэгов с начиная с Internet Explorer 5, хотя в 10 версии эта поддержка была удалена из браузера.
        • 0
          Вот только эта поддержка — разная. IE требовал некоторой обязательной процедуры «регистрации» тега, а остальные браузеры — оборачивают неизвестные теги в HTMLUnknownElement и позволяют навешивать не наго любые стили безо всяких дополнительных настроек.
          • +2
            Все правильно, их инициативу никто тогда не поддержал. Идея опережала свое время.
            • 0
              Какие другие браузеры в 2001 году) Вы о чем?) Микрософт флегматично клал болт на W3C и другие браузеры, потому как в то время совокупная доля IE была под 96%.

              Концепция HTML Components и behaviors, как и HTML Applications, была весьма актуальна и очень перспепктивна на то время. но Микрософт застопорил развитие IE6, увидев в развитии веба конкурента своим десктопным продуктам. Это отлично описано у Джоэла Спольски russian.joelonsoftware.com/Articles/HowMicrosoftLosttheWaronA.html, если кто не читал — крайне рекомендую.
  • +5
    А я вот лично не вижу особенно смысла в Shadow DOM, custom tags и шаблоны:

    1) Shadow DOM: это сознательное зарезание возможностей в угоду не совсем понятно чем — все равно каждый сайт сам стилизует свой плеер или выбирает из имеющихся. Ну и естественно постоянная проблема с кроссбразуерностью. Непонятно, что оно мне должно дать, кроме мобильников, где вся эта стилизация и не нужна.
    2) Custom tags — их писать можно и ладно. Как именно их обрабатывать я могу реализовать и на JS
    3) Не случайно шаблонизаторов так много — у всех разные предпочтени и разные возможности. И сейчас я могу использовать любой, не понятно чем мне поможет еще один на уровне браузера, который еще и наверняка работать будет по разному в разных браузерах.

    Новое API в JS да, полезное.
    • +5
      По мне так SharowDOM это наоборот маст хев фича, с ее помощью, «без геморроя», можно будет кастомизировать стандартные представления. Зачем мне пилить свой плеер, если я могу подправить стили стандартного?
      • 0
        >Зачем мне пилить свой плеер, если я могу подправить стили стандартного?

        Затем, что вы можете выбрать из миллиона уже существующих тот, который нравится именно вам.
        • 0
          Ага, только на практике иногда нужен свой, со своим дизайном. Да бог с ним с плеером, возьмем стандартные компоненты, чекбоксы, радиобаттоны и прочее.
          • 0
            Вот-вот, именно, даже они стилизуются, куда уж более сложным элементам.
    • +3
      1. Не совсем понял мысль вашу мысль о Shadow DOM. Приведу ещё один пример его использования.

        Так выглядит разметка строки поиска google.com
        <fieldset class="gbqff gb_j" id="gbqff">
          <legend class="gbxx"></legend>
          <div id="gbfwa" class="gbqfwa ">
            <div id="gbqfqw" class="gbqfqw ">
              <div id="gbqfqwb" class="gbqfqwc">
                <table cellspacing="0" cellpadding="0" id="gs_id0" class="gstl_0 lst-t" style="height: 27px; padding: 0px;">
                  <tbody>
                    <tr>
                      <td id="gs_ttc0" style="white-space: nowrap;" dir="ltr"></td>
                      <td id="gs_tti0" class="gsib_a">
                        <div id="gs_lc0" style="position: relative;">
                          <input id="gbqfq" class="gbqfif" name="q" type="text" autocomplete="off" value="" style="border: none; padding: 0px; margin: -0.0625em 0px 0px; height: 1.25em; width: 100%; background-image: url(data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D); background-color: transparent; position: absolute; z-index: 6; left: 0px; outline: none; background-position: initial initial; background-repeat: initial initial;" dir="ltr" spellcheck="false">
                          <div class="gbqfif" id="gs_sc0" style="background-color: transparent; color: transparent; padding: 0px; position: absolute; z-index: 2; white-space: pre; visibility: hidden; background-position: initial initial; background-repeat: initial initial;"></div>
                          <input class="gbqfif" disabled="" autocomplete="off" aria-hidden="true" id="gs_taif0" dir="ltr" style="border: none; padding: 0px; margin: 0px; height: auto; width: 100%; position: absolute; z-index: 1; background-color: transparent; -webkit-text-fill-color: silver; color: silver; left: 0px; visibility: hidden;"><input class="gbqfif" disabled="" autocomplete="off" aria-hidden="true" id="gs_htif0" dir="ltr" style="border: none; padding: 0px; margin: 0px; height: auto; width: 100%; position: absolute; z-index: 1; background-color: transparent; -webkit-text-fill-color: silver; color: silver; transition: all 0.218s; -webkit-transition: all 0.218s; opacity: 0; left: 0px; text-align: left;">
                        </div>
                      </td>
                      <td class="gsib_b">
                        <div class="gsst_b" id="gs_st0" style="line-height: 27px;" dir="ltr">
                          <a class="gsst_a" href="javascript:void(0)" aria-label="Listening for "Ok Google"" style="display: none;"><span class="gsri_ha gsst_e" id="gsri_hok0"></span></a><a class="gsst_a" href="javascript:void(0)" aria-label="Search by voice"><span class="gsri_a gsst_e" id="gsri_ok0"></span></a>
                          <div id="chmo">
                            <div id="chm">
                              <div class="chmp">
                                <div class="chmpi chmp"></div>
                              </div>
                              <div style="display: none;">
                                <div class="chma"></div>
                                <div>Not listening. Something went wrong.</div>
                                <div><a>Restart listening</a><a style="padding-left: 10px;">Help</a></div>
                              </div>
                              <div style="display: none;">
                                Hotword detection is off.
                                <div><a>Start listening for "Ok Google"</a></div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </div>
        </fieldset>
        


        Очень много «низкоуровнего» кода. Shadow DOM позволяет скрыть детали реализации элемента и инкапсулировать его стили, чтобы они не конфликтовали с документом. Таким образом в документе строка поиска будет выглядеть как-то так:

          <div class="google-search"></div>
        


        Или так, с использованием custom elements:

          <google-search></google-search>
        


        Детали реализации будут изолированны и лежать где-то в другом месте. Это похоже на разделение интерфейс/реализация в объектно-ориентированных языках.

      2. Подобие custom elements можно написать самому, тут вы правы. Они уже есть в некоторых фреймворках. Ничего нового, только теперь браузер будет поддерживать это нативно.
      3. <template> это не совсем шаблонизатор. Его задача не в том, чтобы взять данные и подставить их в разметку. Это скорее «хранилище» html кода, который вы планируете использовать не сразу, как только документ загрузится, а позже.

        API у него сводится к одному свойству content. Сомневаюсь что браузеры тут могут накуролесить.

      • +1
        Согласен на счет template — очень полезный тег, который позволит хранит шаблон (например) скрытых форм обратной связи или всплывающих подсказок.
        Вот пример pearlplaza.ru/virtual-plan/ — всплывающие подсказки при наведении. Было спроектировано как скрытый div в который подставляются данные из js объекта. По сути используется один и тот же элемент но с разными данными. Во время загрузки страницы браузер парсит div, а если все закрыть в template — парсить не будет.

        Еще пример (более подходящий) — у нас есть страница с комментариями к статье на хабре. Вместо того чтобы изобретать велосипед или шаблон внутри js кода или делать скрытый div а потом копировать его, можно один раз создать template и вставлять его на страницу каждый раз с новыми данными по кнопке «Написать».

        Потенциал Custom Elements и Shadow DOM, мне кажется, еще не раскрыт, однако у меня уже есть мысли как бы я мог применить их.

        Спасибо за статью кстати!
        • +1
          Еще пример (более подходящий) — у нас есть страница с комментариями к статье на хабре. Вместо того чтобы изобретать велосипед или шаблон внутри js кода или делать скрытый div а потом копировать его, можно один раз создать template и вставлять его на страницу каждый раз с новыми данными по кнопке «Написать».
          По сути точно так же оно происходит и сейчас, только не в template, а в div, js или через ajax. Если есть шаблон, то как вы его не назовите он шаблон и есть. И точно так же количество манипуляций не изменится. Мне кажется разница только в том, что раньше мы это делали разными способами, а сейчас эта практика унифицируется.
          • 0
            И унифицируется нативно для html — например, IDE будут лучше поддерживать, чем сборку в JS-скрипте из строк.
            • +1
              Этот html все-равно нужно где-то собирать. Не на клиенте, так на сервере или в прекомпиляции. И делает это не IDE.
              • 0
                Сейчас часто в js можно встретить что-то типа (утрирую)
                var html = '<li><img src="'+ url1 +'"></li><li><img src="'+ url2 +'"></li>...'
                
                . IDE с таким кодом работают плохо. Скрытые теги будут обрабатываться, да и могут нарушать валидность документа. Новый тег от этих проблем избавит.
                • +1
                  Новый тег от этих проблем избавит.
                  Сэр, но как?
                  Куда оно денется? Даже если сделать автоматическую подстановку значений в код шаблона, большая часть таких алгоритмов все-равно работает с условиями, циклами и прочими сложностями. Ну то есть этот алгоритм никуда не исчезнет чудесным образом. Делать компонент для каждого LI тоже не вариант. Это явно проигрывает варианту с js библиотекой темплейтинга.
                  • 0
                    Что помешает сделать новую библиотеку темплейтинга — со всеми требуемыми условиями, циклами и прочими сложностями? Я вот, к примеру, уже предвкушаю, как красиво будет смотреться переделанный на новый лад AngularJS.

                    Исчезнут костыли вида ng-src, нужные лишь затем, чтобы браузер не послал на сервер запрос до подстановки всех переменных. Исчезнут стили, задача которых — скрыть от пользователя служебный мусор — опять-таки, до первого раскрытия переменных.

                    Одно расстраивает. На новую версию AngularJS мы будем десять лет смотреть и облизываться — но не будем его использовать. Потому что нужна совместимость с IE…
                  • 0
                    Для работы с условиями, циклами и прочим мы по-прежнему можем использовать любимые template-библиотеки, вроде Mustache. <template> просто держит ваш шаблон «на готове», как его заполнять данными — дело ваше.

                    Polymer используют Mustache совместно с <template> и Object.observe для подстановки данных в шаблоны: polymer data-bindings.
                    • 0
                      Хотя нет, я не прав. Действительно нужны будут новые библиотеки. Polymer просто одолжил синтаксис своей у Mustache.
                    • +1
                      Во первых, я лично считаю, что этот подход с шаблонами и data-биндингом крайне неэффективен. И точки зрения скорости разработки и с точки зрения производительности. Программировать необходимо на уровне компонентов, а биндинг данных должен осуществляться самым эффективным образом в коде компонента или вообще по возможности платформой и не манипулируя отдельными элементами и атрибутами DOM. И соответственно реализовал этот подход в своей библиотеке controls.js
                      Но мы не об этом, а о том что
                      var html = '...'
                      сам по себе с введением обсуждаемых подходов не исчезнет. Он может перекочевать частично в dom template, но только частично, логика останется в коде. И в итоге получится возможно сложнее если делать с использованием dom template. А эффективности работы с DOM сами понимаете.
                      В то время как сейчас можно совершенно спокойно выбросить такой код в компоненты уже существующих JS библиотек и избавиться и от этой лапши, и от затрат на DOM. Уже сейчас все это лаконично и шустро работает, даже без shadow dom.
                      • 0
                        Я думаю, создавать сотню скрытых DOM элементов не правильно (особенно с картинками). Компоненты, перечисленные в статье в большей степени помогут в фронтенд разработке. Например тот же Meteor.js уже использует template во всю.

                        Мне, почему-то вспомнились слайдеры, которые сегодня используются повсеместно, одна лишь возможность делать слайдер с помощью template уже греет душу.

                        Мое мнение таково:
                        — Меньше костылей в коде.
                        — Легче делать отзывчивые асинхронные приложения.
                        — И как сказано ниже в комментариях «У кастомных тэгов можно задавать свой прототип для объектов DOM — вот это реально крутая вещь»
                        • 0
                          Мне, почему-то вспомнились слайдеры, которые сегодня используются повсеместно, одна лишь возможность делать слайдер с помощью template уже греет душу.
                          Какое именно предполагается в этом преимущество? Вы хотите вставить слайдер именно в DOM и редактировать его DOM дереве? Если вставить в основную страницу, то это очень плохая идея. Если шаблон в отдельном html файле, то это будет менее эффективно, чем компонентная система на JS. Если вы хотите редактирвать в IDE, то это не проблема и задача shadow DOM. Это можно сделать и сейчас существующими средствами и эффективнее.
                          У меня есть простой пример компонента carousel, он конечно не редактируется сейчас в IDE, но мог бы, если бы IDE этого захотело.

                          — И как сказано ниже в комментариях «У кастомных тэгов можно задавать свой прототип для объектов DOM — вот это реально крутая вещь»
                          Не могли бы вы пояснить зачем вообще это нужно? Зачем нам прототипы в DOM? Нужно наоборот избегать манипуляции элементами DOM.
                          • 0
                            Карусель, которую Вы привели в пример, не семантична изначально ну и ID в веб инспекторе смотрится страшно.

                            Когда я говорил про слайдер, я имел ввиду ситуацию с предзагрузкой изображений.
                            • 0
                              Карусель, которую Вы привели в пример, не семантична изначально ну и ID в веб инспекторе смотрится страшно.
                              Вас напугали картинки закодированные в коде страницы? Ну так это не элемент семантики. Замените в уме эти картинки привычными вам img src="". Это же просто страничка так сделана, что бы без внешних файлов можно было скопировать.

                              Когда я говорил про слайдер, я имел ввиду ситуацию с предзагрузкой изображений.
                              Не совсем понимаю связь template с предзагрузкой изображений. Не могли бы вы пояснить, как сделать предзагрузку картинок с помощью template? И вопрос про прототипы остается.
                              • +1
                                Не совсем понимаю связь template с предзагрузкой изображений. Не могли бы вы пояснить, как сделать предзагрузку картинок с помощью template?

                                Как раз таки предзагрузки картинок не будет пока слайдер не дойдет до нужного слайда. Просто на событие onslide вешается код вставки слайда (с картинками) с использованием template.

                                И вопрос про прототипы остается.

                                Кастомные элементы способны хранить в себе методы и вести себя так как необходимо разработчику. Элемент div это лишь контейнер который не несет в себе никакой нагрузки, в то время как тот же audio подгружает целый скин плеера. Таким образом мы можем создавать на странице элементы типа audio и прочее со своей логикой. В примере выше приводился код гугл-поиска и кнопки лайков. Думаю это самые яркие примеры.
                            • 0
                              По поводу ID, это не обязательный элемент технологии, шаблон для любого элемента можно сделать без ID. Поэтому не пугайтесь, это тоже особенность реализации этих конкретных шаблонов. Но вообще в этой теме мы обсуждаем очень сильное усложнение дерева DOM и потенциально все это приведет к закрытости части публичных «компонентов», их обфускации, привыкайте и готовьтесь.
                              • +1
                                с выключеным JS я увижу что то вроде этого?
                                [carousel parameters]
                                [slide active] slide content [/slide]
                                [slide] slide content [/slide]
                                [/carousel]

                                по моему это не семантично
                                • 0
                                  Нет, вы увидите статичный html. Что он будет отображать, статичный кадр страницы, JS-less версию страницы или сообщение о неработоспособности без JS, это как веб-мастер решит. Мне не очень хотелось включать компиляцию внутренних страниц сайта в html, поэтому у меня там только сообщение.
                                  • +1
                                    На мой взгляд, создавать велосипеды шаблонизации не стоит, так как лучшие практики уже получили место в стандартах и называется это template. А код с квадратными скобками это затычка, которая была необходима, до появления нативной поддержки. В HTML должны быть теги для разметки, атрибуты к тегам и ничего более.

                                    Точно так же вымерли текстуры закругления углов, двойные рамки, градиенты и так далее. Скоро текстуры из Web совсем вымрут и останутся только иконки и изображения есущие смысловую нагрузку. По сути бэкграунд изображением для отображения градиента — скорее временная мера которая вышла сейчас из моды чем нечто более удобное чем линейный градиент в CSS.

                                    Я тут подумал сегодня и прикинул как бы смотрелись новые jQuery плагины которые вызываются кастомными тегами, а вся разметка уходит в shadow DOM
                                    • 0
                                      Это было бы здорово, если бы консорциум w3 не ошибался, но к сожалению это не так. У них есть совершенно лажовые и не используемые разделы стандарта. Язык JS имеет серьезные огрехи проектирования и значительная часть кода библиотек направлена только на обход этих недостатков. Это все дает веские основания не верить вашему мнению о том, что стандарт вбирает лучшие практики. Компоненты в веб появились кучу лет назад, но w3 их только сейчас начинает внедрять, да и то под напором ребят из гугла. А вместо этого они шли по совершенно тупиковому пути вводя узкоспециализированные теги. Есть такие тэги о которых вы скорее всего даже и не знаете.
                                      За критику, упоминания про велосипед и затычку, да, спасибо. Почему-то, мой велосипед работает быстрее чем фреймворки и решает дополнительный круг задач. Разметка проще чем в википедии и имеет больше возможностей. Я с его помощью могу писать приложения на node-webkit и делать многие вещи, которые вы с template не сможете. Без квадратных скобок обойтись не представляется возможным.
                                      Для использования обсуждаемых новых возможностей в моей библиотеке скорее всего не потребуется ничего менять, архитектура полностью совместима, я могу использовать в своих компонентах template&shadow DOM.
                                      Поэтому нет, не велосипед и нет, не затычки.
                                      • 0
                                        Про квадратные скобки тут немного другая история. Просто это не совсем те скобки, что вы привыкли видеть. Да, это bbCode, но тут текст внутри квадратных скобок может иметь другую, несовместимую с html разметку. Html имеет на это ограничения. Поэтому все-таки квадратные скобки остаются.
                                        • 0
                                          Я не вижу смысла спорить. Каждый останется при своем мнении в любом случае. У меня в голове долго складывались принципы создания качественных веб приложений, У Вас они свои.

                                          Не понимаю, почему слово «велосипед» вызвало негатив, Велосипед не костыль. Это что уже было изобретено, без использования сторонних концепций.

                                          У меня как то тоже недавно была идея добавить библиотеку в PHP которая позволяла бы простые типы хранить в объектах, а вместо функций использовать методы этих объектов (под впечатлением от Python и JS), однако я отказался от этой идеи, после долгих анализов ситуации, так как пришел к выводу что данная библиотека будет являться костылем для PHP и лучше в таком случае использовать другой язык, с нативной поддержкой.

                                          Аналогично Вашему случаю — появилась нативная поддержка, следовательно можно облегчить код и клиент-сайд для ускорения работы приложения.
                                          • 0
                                            У меня как то тоже недавно была идея добавить библиотеку в PHP которая позволяла бы простые типы хранить в объектах, а вместо функций использовать методы этих объектов (под впечатлением от Python и JS)


                                            Сразу вспомнилось вот это творение Антона Шевчука.
                      • 0
                        Дата-биндинг отдельная тема, тут я согласен.

                        Я понимаю, о чём вы. Да, уже существует множество решений проблем шаблонов. На любой вкус и цвет, и работают они довольно быстро.

                        По поводу подхода var html = '<img src="' + image +'>"'. Он может быть только временным решением. Библиотеки шаблонов, по сути, делают тоже самое, только эскейпят данные. Вариант сносный, но выглядит скорее как хак.

                        От работы с DOM в любом случае не уйти. Даже если мы собрали строку с данными, её нужно вставить в DOM. Давайте сравним два подхода пошагово.

                        Строки
                        1. Получить строку шаблон.

                          a). Загрузить AJAX-ом
                          б). Найти в DOM элемент, содержащий шаблон, извлечь шаблон оттуда.

                        2. Провернуть множество операций со строками. Эскейпить данные вручную.

                        3. Вставить получившуюся строку в DOM. Браузер парсит строку, рендерит содержимое.


                        <template>
                        1. Получить содержимое <template>.

                          Найти в DOM тег <template> с нужным шаблоном. Его содержимое уже распаршено, с ним можно работать как с любым элементов в DOM.

                        2. Подставить данные, используя DOM API. Нет необходимости заботится о вредоностности данных.

                        3. Вставить элемент DOM в… DOM. Браузеру не нужно ничего парсить, он сразу рендерит содержимое.

                        Сложно сказать, какой подход будет быстрее, пока нет бенчмарков. Но вариант с <template> определённо однородней и «чище».

                        Да, скорость работы DOM пока ещё проблема. Но мы, в случае с <template> работаем на очень ограниченном его «участке».

                        Уже сейчас все это лаконично и шустро работает, даже без shadow dom.

                        Shadow DOM не влияет на работу шаблонов.
                        • +1
                          Еще раз повторяю, вот этого " Подставить данные, используя DOM API. Нет необходимости заботится о вредоностности данных." не будет. Это фантастика. Это вы так предположили, но это не так. Никто такого еще не придумал, хотя пытались. Логика интепретации шаблона или слишком проста и не удовлетворяет, или построена на сложных правилах, или требует языка программирования. Где-то требует яп, где-то нет, но подход должен быть общим, поэтому в общем случае требует. Поэтому в общем случае с шаблонами в DOM решение будет и сложнее, и медленнее. Единственное кажущееся преимущество, это возможность с помощью IDE редактировать шаблон в виде какого-то визуального редактора. Но опять же, это ошибочное предположение. Это можно сделать и сейчас без всяких шаблонов в DOM и лучше будет если без них.
                          • 0
                            Да почему вдруг — фантастика, никто не придумал и этого не будет? Это, между прочим, уже есть. И этим пользуются.
                          • 0
                            Это не фантастика, и это уже придумали. Angular, например, делает именно так.
                            • 0
                              Вы сами себе противоречите, Angular делает это через JS, это не соответствует вашему п.2.
                              • 0
                                Вы о чем?
                                2. Подставить данные, используя DOM API. Нет необходимости заботится о вредоностности данных.
                                Где тут написано, что это должно делаться без js?
                              • +1
                                DOM API это и есть JS… Это интерфейсы вроде HTMLElement, методы вроде appendChild() и cloneNode(), атрибуты вроде innerHTML. Вы что-то другое имеете ввиду под DOM API?
                                • 0
                                  Я не могу понять вот этого:
                                  2. Провернуть множество операций со строками. Эскейпить данные вручную.
                                  и
                                  2. Подставить данные, используя DOM API. Нет необходимости заботится о вредоностности данных.
                                  Почему во втором случае у вас получается без кода логики и не нужно эскейпить.
                                  • +2
                                    Я не говорил, что без кода логики. Логика на JS, с использованием DOM. Не нужно эскейпить, потому что setAttribute(), textContent и им подобные сделают это за вас.
                        • –1
                          a). Загрузить AJAX-ом
                          б). Найти в DOM элемент, содержащий шаблон, извлечь шаблон оттуда.

                          Найти в DOM тег <template> с нужным шаблоном. Его содержимое уже распаршено, с ним можно работать как с любым элементов в DOM.

                          А куда делся аякс во втором варианте? Если вы заранее подгружаете шаблон в виде <template>, то вы точно также можете его без аякса подгрузить сразу и сейчас. А если вы подгрузили шаблон за ранее и он представляет из себя просто HTML без специальной разметки под вставку данных (как я вижу из примеров <template> предоставляет именно такое), то вы можете сразу создать из этого documentFragment и не вставлять его в DOM. А, когда нужно, взять его и
                          Подставить данные, используя DOM API. Нет необходимости заботится о вредоностности данных.

                          Тогда в чем отличие? В том, что documentFragment нужно где-то хранить и он занимает память? Если вам это так критично, то не создавайте его заранее, а просто вместо
                          Провернуть множество операций со строками. Эскейпить данные вручную.
                          Вставить получившуюся строку в DOM. Браузер парсит строку, рендерит содержимое.

                          создавайте documentFragment и работайте с ним через DOM API. Потом его вставляйте.

                          Собственно виджеты, которые есть в крупных фреймворках давным-давно, например, в Dojo, так и делают. Есть template: размеченный HTML. Есть JS: логика этого виджета. Внутри логики шаблон виджета доступен через свойство domNode в котором лежит documentFragment, который потом можно вставить в нужное место. Shadow же позволяет просто отображать эту domNode в веб-инспекторе в виде одного тэга. И то пока не поставлена галочка показывать призраков.

                          Сейчас страницы стали сложными и все фреймворки так или иначе приходят к идеям виджетов. Ребята в W3C это поняли и решили тоже запилить. Вероятно, иметь это нативно в браузере это хорошо, но это явно не стоит всех тех восторгов, которые по этому поводу высказываются. Плюс, судя по всему ребята решили сами пройти весь путь и поэтому, пока они соберут все грабли и сделают механизм сравнимый по удобству с тем, что сейчас предоставляют фреймворки, пройдет порядочно времени.
                  • 0
                    Сэр, но как?
                    Куда оно денется?

                    Просто в html-коде будет что-то вроде
                    <template>
                      <li></li>
                      <li></li>
                    </template>
                    

                    которое нормально распарсится IDE.
                    • 0
                      Такой пример распарсится. Это logic-less шаблон. Большинство шаблонов у компонентов не такие. Поэтому логика останется в коде. Я же спрашиваю вас про шаблоны с логикой. html он без логики, что бы добавить в него шаблоны нужно добавить и логику.
                      Каждый уважающий себя разработчик должен написать свой шаблонизатор, ребята этим и занимаются. Это обычные ребята, есть примеры в w3 стандартах совершенно не применимых в реальной жизни вещей. Помня примеры той лажи я не предполагаю по дефолту, что ребята очень продуманные. Они что-то внедряют, но будет ли это применимо время покажет.
                      • 0
                        Вы сейачс с кем спорите-то? Кто-то утверждает, что с новым тегом больше не нужна логика?
                        • +2
                          Нет, я больше спрашиваю. Спрашиваю, зачем вообще нужен этот тэг. Мне отвечают что-то вроде «создаешь шаблон, данные сами туда фьюить, и готово, и не надо ничего эскейпить, оно само! И это будет крута!». А я не могу понять в чем крутизна, и почему не нужно эскейпить, и как оно туда само залезет.
                          Ну да ладно, будет больше рабочих примеров, там и увидим.
                          • 0
                            оздаешь шаблон, данные сами туда фьюить, и готово

                            Кто и где такое говорит? Лично я только о том, что предложенные шаблоны органичнее вписываются в html и в процесс разработки вообще, чем сборка их в JS из строк.
                          • 0
                            и не надо ничего эскейпить
                            Да, я именно так и говорил. Где вы тут нашили «и не надо никакого js»?
  • +1
    > Содержимое тегов парсится браузером, но не вызывает выполнение скриптов

    Вообще скрипты итак не выполняются при вставке с помощью innerHTML.

    Web Components — интересная спецификация, но пока я вижу 3 проблемы:
    1. отсутствие стандартизации у кастомных тегов
    2. непонятно как будут обстоять дела у кастомных элементов с SEO
    3. кроссбраузерная поддержка

    Однако в некоторых случаях кастомные тэги — это то, что доктор прописал. Например, всякого рода кнопки like и +1 — очень хорошие кандидаты. Но повторяю — не везде их применение имеет смысл.
    • 0
      По поводу проблем 2 и 3 согласен. Да, кнопки like и +1 действительно показательный кейс. Что вы имеете ввиду под стандартизацией кастомных тегов?

      > Содержимое тегов парсится браузером, но не вызывает выполнение скриптов

      Вообще скрипты итак не выполняются при вставке с помощью innerHTML.

      Я имел ввиду, если браузер загружает документ, в котором есть такой код:

        <template>
          <script>alert(1);</script>
        </template>
      

      alert(1); не выполнится до тех пор, пока мы не сделаем импорт содержимого шаблона:

        var tmpl = document.querySelector('template');
        var tmplBody = document.importNode(tmpl.content);
      
        document.body.appendChild(tmplBody);
      
      • +1
        > Что вы имеете ввиду под стандартизацией кастомных тегов?
        Представьте ситуацию когда любой уважающий себя разработчик будет создавать кастомный тэг для табов. Если брать HTML5, например, там есть спека в которой четко описано что делает тэг, какие у него могуть быть дочерние элементы и т.д. И это очень здорово, т.к. у нас есть набор тэгов которые все одинаково понимают. С кастомными тэгами такого не будет. По сути <my-tabs/> будет эквивалентен <ul class="my-tabs"/>. Поэтому в плане ускорения стандартизации никаких значительных плюсов у кастомных тэгов нет перед теперешним подходом создания виджетов.
        • 0
          У кастомных тэгов можно задавать свой прототип для объектов DOM — вот это реально крутая вещь. А использование их исключительно в разметке — действительно, ничем от подхода с классами не отличается.
        • 0
          Такого рода стандартизация по-моему будет скорее мешать. Умный ход — выпустить API которое позволяет программистам делать всё что они хотят, а потом взять лучшие практики и сделать их стандартом. Поступать наоборот — риск.

          Я надеюсь, если web components пойдут в народ, появятся библиотеки элементов, вроде bootstrap, yui и т.д. У них будут свои, внутренние, стандарты и лучшие практики.
          • 0
            Вот тут с вами не соглашусь. Стандарты нужны иначе будет анархия, когда под одним и тем же понятием каждый человек будет понимать что-то свое.

            Воообще ничего не мешат уже сейчас взять и выбрать лучшие компоненты из существующих библиотек и стандартизировать. Но почему-то этого не делают. С появлением кастомных тэгов вряд ли ситуация изменится в лучшую сторону.
  • +1
    Вы извините, что немного не по теме, но возник вопрос:
     <img src="bad-url"></img> <!-- почему так-то? -->
     <img src="bad-url" />     <!-- а не так? -->
    
    • 0
      Привычка… В html5 и так можно:

        <img src="bad-url">
      
      • 0
        Не только можно, но и нужно. Самозакрывающие теги (или как они там правильно называются) вообще не поддерживаются в html. Попробуйте написать
        <script src="..." />
        и поймете, почему этот слэш в конце тэга — суть самообман.
      • 0
        Понял, спасибо за ответ, просто не сталкивался с таким.
  • 0
    Я уже больше года с большой надеждой наблюдаю за развитием этого стандарта. По-моему, только web components смогут наконец положить конец леденящему душу ужасу, что творят сейчас разработчики, пытаясь разобраться, как работать с повторным использованием кода, сфокусированного на элементах страницы, а не на внутреннем устройстве собственно кода. Текущий предел инженерной мысли – календарик и пара плагинов от гигантов.

    Подскажите, может уже появился какой-нибудь достойный внимания репозиторий для web components? Я ни одного еще найти не смог.

    PS. Надеюсь, remote modules не выпилят из js harmony. Этой фиче тут самое место.
    • 0
      Что вы имеете ввиду, говоря о «репозитории для web components»? Polymer разрабатывает элементы на основе web components. Та же команда, занимается написанием полифилов, которые имитируют части стандарта: custom elements, shadow dom и т.д.
      • 0
        Я имею в виду что-нибудь наподобие npm – ресурса, где можно:
        * искать по названию/описанию компонентов
        * фильтровать по тегам
        * сортировать компоненты по количеству пользователей/зависимых компонент
        * изучать дерево зависимостей
        • 0
          Для этого вполне подойдёт bower или component. Не думаю что есть смысл делать специализированный репозиторий только для кода на Web Components.
        • 0
          Сегодня наткнулся: http://customelements.io/
          • 0
            О, это в точности то, что я искал! Спасибо.
  • 0
    Составляющие стандарта Web Components описаны неплохо, но в чем, собственно, суть заголовка «Web Components — будущее Web»? Да и многое из того, что мы используем сейчас можно переиспользовать…
  • 0
    Новый стандарт возможно изменит подходы к написанию web-приложений на клиенте. Это основная мысль статьи, отсюда заголовок.

    Переиспользовать вёрстку полноценно не можем. Нет механизмов инкапсуляции, ни стилей, ни фрагментов вёрстки.

    Шаблоны, в том виде в котором они есть, это хак. Представьте, что в JS вы вместо того, чтобы использовать функции, вставляете их содержимое везде, где должны быть вызовы функций. Это примерно то что происходит сейчас с HTML и CSS.
  • +2
    Когда-нибудь мечтали о том, чтобы в HTML был тег <menu>

    Зачем об этом мечтать, если он ещё со времён HTML 3.2 есть, а может и раньше был…
    А в HTML 5 ещё и nav добавили…
    Тут ещё и кастомные будут уже явным перебором.
    • 0
      Ну что ж вы так сразу с места в карьер… Тактичнее надо. :)
    • 0
      Про <menu> буду знать, спасибо. Хотя он кажется не особо используется.
  • 0
    Автор, скажите, как произошел термин «проекции»? В оригинале это «insertion points» — дословный перевод «точки вставки», «курсор». Я не спорю, перевод этого термина как «проекции» довольно точно отображает суть, но все же, это лично ваш вариант перевода или это подчерпнуто в каких-то документах?
    • 0
      Термин «проекция» используется в статьях о shadow dom, здесь например. Так называют процесс, который происходит при использовании insertion points.

      Тег <content> создаёт insertion point, куда проецируется содержимое хоста.

      Кое-где в W3C драфте также есть упоминания.
      • 0
        Ок, действительно процесс — это проецирование, проекция. Как по вашему мнению точнее перевести «insertion points»? «Точки проекции»?
        • 0
          Думаю, «точки вставки» точнее. Если бы они имели ввиду «точки проекции», было бы «projection points».
      • 0
        Насколько я понял ситуация в терминах немного изменилась.
        w3c.github.io/webcomponents/spec/shadow/#distributions
        Теперь это «distribution», так получается?
        • 0
          distribution — это процесс распределения содержимого хоста между insetion points. Распределение происходит с помощью атрибута select тега <content>. Как в этом примере (для просмотра нужен Chrome Canary со включенными флагами).

          Допустим хост выглядит так:

            <article>bla bla</article>
            <div class="picture"></div>
          


          Тогда мы можем проецировать не весь контент, а его части, в разные insertion points, например:

            <content select="article"></content>
            <figure>
              <content select=".picture"></content>
            </figure>
          
  • 0
    Из примера в статье:

    imported = document.importNode(content);
    


    Из W3C Introduction to Web Components:

    var comment = t.content.cloneNode(true)
    


    Что вернее? Почему?
    • 0
      importNode() клонирует и «выполняет» разметку (начинает загружать картинки итд).
      cloneNode() только клонирует, «выполнение» происходит при вставке клона в документ.

      Когда что использовать зависит от ситуации. При прочих равных, я считаю, importNode() использовать логичнее.
  • 0
    Флаг chrome://flags/#enable-html-imports нынче отсутствует вовсе.

    filipovskii.github.io/web-components-demo/wc-templates не завёлся
    filipovskii.github.io/web-components-demo/wc-todo-demo не работает тоже

    а за статью спасибо. крутые штуки

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.