Концепция «Родные Элементы»(Native Elements)

от автора

Всем доброго здравия.
Хотел предложить концепцию JavaScript(JS) библиотеки для удобного использования Custom Elements(по-русски назову «собственные элементы»). Перед тем как предлагать Polymer, X-Tag, Bosonic и другие, прошу прочитать текст до конца.

Введение

Главная идея состоит в том, чтобы сделать использование собственных элементов более похожим на нативный подход стилизации встроенных HTML-элементов. Например, я определил элемент вертикальной гистограммы(ui-vboxhistogramm). Добавил несколько гистограмм на страницу. В случае использования Polymer мне необходимо описывать визуальный стиль для каждой гистограммы по отдельности. И в случае повторения визуальных свойств(не CSS-свойств, а определённых вручную для собственного элемента) для каждой гистограммы описание становится избыточным. Поясню на примере:

<ui-vboxhistogramm id="histo1" column-count="5" column-width="10px"></ui-vboxhistogramm> <ui-vboxhistogramm id="histo2" column-count="5" column-width="10px"></ui-vboxhistogramm> <ui-vboxhistogramm id="histo3" column-count="5" column-width="10px"></ui-vboxhistogramm> 

Тут сразу напрашивается система классов из HTML. Но классы работают только для нативных CSS-свойств. В итоге возникла задача сделать похожую систему классов на JS.

Концепция «Родные Элементы»(Native Elements)

В первую очередь хотелось бы сделать доступ к свойствам визуализации по аналогии с нативным стилем изменения этих свойств:

divElement.style.background = "color"; 

Собственные элементы позволяют воплотить в жизнь эту дерзкую идею:

class ExtendedCSSStyleDeclaration {   constructor(parentNode)   {     this._root = parentNode;   }   declare(declarationObject)   {     //тут мы получаем свойства для описания собственного элемента и применяем их в соответствии с названием сеттера   } }  class VBoxHistogrammCulumnStyle extends ExtendedCSSStyleDeclaration {   constructor(parentNode)   {     super(parentNode);   }   set count(value){}   get count()     {}   set width(value){}   get width()     {} }  class VBoxHistogrammStyle extends ExtendedCSSStyleDeclaration {   constructor(parentNode)   {     super(parentNode);     this.column = new VBoxHistogrammCulumnStyle(this);   }    set title(value)   {     //Перед тем как изменить внешний вид элемента сначала сохраняем значение в специальный контейнер,     //так как значение может задаваться из разных мест(напрямую или через группу(класс)), поэтому надо иметь возможность получать оба значения, а точнее последнее.     saveProperty(this, "width", value);     this._root.style.width = this.width;   }   get width()   {     return getLastProperty(this, "width");   } }  class VBoxHistogrammProto extends HTMLElement {   createdCallback()   {     this.xstyle = new ExtendedCSSStyleDeclaration(this); //передаём указатель на узел нашего элемента для дальнейших манипуляций с ним   } } 

Теперь мы можем задавать стиль для наших элементов по аналогии с нативным подходом и/или даже более продвинутым способом:

Группы — они же классы

Возвращаемся к вопросу стилизации через классы. Так как ключевое слово class уже зарезервировано для этого атрибута, то наиболее близким по значению названием для него по моему мнению является ключевое слово group. Группировка элементов происходит по аналогии с заданием класса для встроенных элементов:

<ui-vboxhistogramm id="histo1" group="histogroup1"></ui-vboxhistogramm> <ui-vboxhistogramm id="histo2" group="histogroup1"></ui-vboxhistogramm> <ui-vboxhistogramm id="histo3" group="histogroup1 histogroup2"></ui-vboxhistogramm> 

Теперь наши элементы сгруппированы по общим сходным свойствам, определенным вручную в собственном элементе. Декларация групп происходит в JS-коде:

declareGroup( {   histogroup1:   {     width: "100px",     column:     {       count: 5,       width: "10px"     }   },   histogroup2:{} }); 

Алгоритм декларации группы реализуется следующим образом. В момент создания собственного элемента(функция обратного вызова createdCallback) необходимо организовать список групп(например в глобальном объекте window) с очередью из группируемых элементов на применение с помощью специального объекта groupList.

groupList — это аналог нативного classList только для собственного элемента. Он также имеет методы add и remove. Метод add(по аналогии с методом declare для отельного элемента) принимает декларационный объект, содержащий в себе описание визуальных свойств элемента. Таким образом функция declareGroup обходит все группы из своего декларационного объекта и добавляет их для всех элементов из очереди.

Приоритет задаваемых свойств можно реализовать по аналогии с классами. Если свойство задаётся напрямую через сеттер или метод declare, то свойства из групп теряют свою силу, то есть перекрываются.

Заключение

В итоге мы получаем близкий к нативному метод описания визуальных свойств для собственных элементов, содержащий в себе ряд преимуществ и недостатков. Хотелось бы послушать мнение знающих front end разработчиков, чтобы определится с целесообразностью реализации этого подхода.

Применяете ли вы Веб Компоненты в ваших рабочих проектах?

Проголосовал 1 человек. Воздержавшихся нет.

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

ссылка на оригинал статьи http://habrahabr.ru/post/273367/