Розробка Web Components (Custom Elements): повний цикл створення

Розробка Web Components (Custom Elements) для сайту

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка Web Components (Custom Elements): повний цикл створення
Середній
~3-5 днів

Наші компетенції:

Часті запитання

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1461
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1314
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1014
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1275
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1019
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1019

Розробка Web Components (Custom Elements) для сайту

Інтеграція складної UI-логіки в проєкт без фреймворків — головний біль. Ми часто стикаємося із задачею створити перевикористовуваний елемент, який однаково добре працює і в WordPress, і в Laravel Blade, і в статичному HTML. Рішення — Web Components — набір нативних браузерних API, які дозволяють розробляти власні HTML-елементи з інкапсульованою логікою та стилями. Жодних залежностей від React, Vue або jQuery. Компоненти живуть в будь-якому HTML-контексті.

Три складові: Custom Elements API (реєстрація нового тега), Shadow DOM (інкапсуляція стилів), HTML Templates (шаблонізація). Використовуються незалежно або разом. Досвід нашої команди — 10+ років у продакшені (Бітрікс, 1С, веб-розробка), 5+ років розробки нативними засобами, понад 10 проєктів з Web Components. Гарантуємо крос-браузерну сумісність та продуктивність.

Основні проблеми при інтеграції кастомних елементів

Перша проблема — конфлікт стилів. Без Shadow DOM вбудовані стилі можуть перевизначатися глобальними CSS-правилами. Друга — відсутність реактивності: на відміну від фреймворків, нативні елементи не оновлюються автоматично при зміні атрибутів. Третя — складність тестування: потрібне середовище з підтримкою Custom Elements. Ми вирішуємо ці проблеми за рахунок продуманої архітектури та використання TypeScript.

Як ми це робимо (доказ експертності)

На одному з проєктів для великого банку ми розробили бібліотеку з 8 кастомних елементів (акордеон, таби, сповіщення, дропдаун, модальне вікно, пагінатор, картка товару, слайдер) для заміни jQuery-плагінів. Результат: розмір сторінки зменшився на 200 КБ, а швидкість завантаження зросла на 15%. При цьому компоненти використовувалися і в WordPress, і в React-адмінці без змін. Така економія ресурсів — прямий наслідок відсутності залежностей та легкості нативних елементів.

Як створити кастомний елемент з нуля?

Процес складається з п'яти кроків:

  1. Спроектувати API компонента — визначити атрибути, події та публічні методи.
  2. Написати клас, успадкований від HTMLElement.
  3. Реалізувати методи життєвого циклу (connectedCallback, attributeChangedCallback тощо).
  4. Зареєструвати елемент через customElements.define().
  5. Протестувати в декількох браузерах.

Ось типовий приклад — компонент сповіщення:

class ToastNotification extends HTMLElement { private shadow: ShadowRoot private messageEl: HTMLElement | null = null static get observedAttributes() { return ['type', 'message', 'duration'] } constructor() { super() this.shadow = this.attachShadow({ mode: 'open' }) } connectedCallback() { this.render() const duration = parseInt(this.getAttribute('duration') || '3000') if (duration > 0) { setTimeout(() => this.dismiss(), duration) } } disconnectedCallback() { this.messageEl?.removeEventListener('click', this.dismiss) } attributeChangedCallback(name: string, oldVal: string, newVal: string) { if (oldVal !== newVal && this.isConnected) { this.render() } } private render() { const type = this.getAttribute('type') || 'info' const message = this.getAttribute('message') || '' this.shadow.innerHTML = ` <style> :host { display: block; font-family: inherit; } .toast { padding: 12px 20px; border-radius: 8px; font-size: 14px; line-height: 1.4; cursor: pointer; animation: slide-in 0.3s ease; } .toast--info { background: #1a1a2e; color: #7eb8f7; border: 1px solid #2a4a7f; } .toast--success { background: #0d2e1a; color: #5cb85c; border: 1px solid #1a5e30; } .toast--error { background: #2e0d0d; color: #e74c3c; border: 1px solid #7f1a1a; } @keyframes slide-in { from { transform: translateY(-10px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } </style> <div class="toast toast--${type}" part="toast"> ${message} </div> ` this.messageEl = this.shadow.querySelector('.toast') this.messageEl?.addEventListener('click', this.dismiss) } private dismiss = () => { this.dispatchEvent(new CustomEvent('toast-dismiss', { bubbles: true, composed: true, })) this.remove() } show(message: string, type = 'info') { this.setAttribute('message', message) this.setAttribute('type', type) if (!this.isConnected) { document.body.appendChild(this) } } } customElements.define('toast-notification', ToastNotification) 

Використовувати можна і через HTML, і через JS.

Життєвий цикл і TypeScript

Custom Elements надають чотири методи життєвого циклу: constructor, connectedCallback, disconnectedCallback, attributeChangedCallback. Для коректної інтеграції з TypeScript потрібно оголосити типи в HTMLElementTagNameMap:

declare global { interface HTMLElementTagNameMap { 'toast-notification': ToastNotification } } 

Типізація custom elements — важливий крок для створення бізнес-компонентів з автодоповненням в IDE.

Метод Коли викликається Що робити
constructor При створенні елемента Ініціалізація стану, створення Shadow DOM
connectedCallback При додаванні в DOM Встановлення обробників, завантаження даних
disconnectedCallback При видаленні з DOM Очищення обробників, таймерів
attributeChangedCallback При зміні відстежуваного атрибута Оновлення представлення

Коли Shadow DOM не потрібен?

Shadow DOM додає ізоляцію, але й складність. Для простих елементів (наприклад, лічильник або розкривний список) достатньо Light DOM — стилі успадковуються від батька, код простіший. Приклад акордеона:

class AccordionItem extends HTMLElement { private header!: HTMLElement private content!: HTMLElement private isOpen = false connectedCallback() { this.innerHTML = ` <button class="accordion-header" aria-expanded="false"> <slot name="header"></slot> <svg class="accordion-icon" viewBox="0 0 24 24"> <path d="M6 9l6 6 6-6"/> </svg> </button> <div class="accordion-content" role="region" hidden> <slot name="content"></slot> </div> ` this.header = this.querySelector('.accordion-header')! this.content = this.querySelector('.accordion-content')! this.header.addEventListener('click', this.toggle) } private toggle = () => { this.isOpen = !this.isOpen this.header.setAttribute('aria-expanded', String(this.isOpen)) this.content.hidden = !this.isOpen } disconnectedCallback() { this.header?.removeEventListener('click', this.toggle) } } customElements.define('accordion-item', AccordionItem) 

Порівняння підходів

Параметр Shadow DOM Light DOM
Інкапсуляція стилів Повна Ні
Складність Вища Нижча
Продуктивність Однаково Однаково
Підходить для Бібліотек, складних віджетів Простих інтерактивних елементів
Підхід Час на перший компонент Повторне використання Залежності
Web Components 4-8 годин 100% в будь-якому проєкті Ні
React компонент 2-4 години тільки в React 40KB
Vue компонент 2-4 години тільки в Vue 30KB

Що входить в роботу?

  • Проектування API компонента
  • Реалізація на TypeScript з повним життєвим циклом
  • Написання декларацій типів
  • Інтеграція з існуючим проєктом
  • Документація з використання та кастомізації
  • Підтримка протягом місяця після здачі

Орієнтири за строками

Один простий компонент без Shadow DOM — від 4 до 8 годин. Комплексний компонент з анімаціями, тестами та TypeScript — 1–3 дні. Бібліотека з 5–10 компонентів — 1–2 тижні. Вартість розраховується індивідуально після аналізу вашого проєкту. Зв'яжіться з нами для безкоштовної консультації — ми оцінимо впровадження та запропонуємо оптимальне рішення.

Типові помилки при розробці Custom Elements

Одна з найпоширеніших помилок — забути зареєструвати елемент до його використання в HTML. Інша — використовувати Shadow DOM там, де достатньо Light DOM, що ускладнює стилізацію ззовні. Також часто ігнорують метод disconnectedCallback, що призводить до витоку пам'яті через неповне зняття обробників. Ми завжди перевіряємо ці моменти.

Замовте розробку Web Components під ключ — отримайте надійні, незалежні елементи для будь-якого сайту. Отримайте консультацію — ми відповімо на всі питання та допоможемо обрати оптимальний підхід.