فارسی

قدرت کامپوننت‌های وب، با تمرکز بر عناصر سفارشی، برای ساخت مؤلفه‌های UI قابل استفاده مجدد و کپسوله شده در برنامه‌های مختلف وب را کاوش کنید.

کامپوننت‌های وب: نگاهی عمیق به عناصر سفارشی (Custom Elements)

کامپوننت‌های وب نمایانگر یک پیشرفت قابل توجه در توسعه وب هستند و روشی استاندارد برای ایجاد کامپوننت‌های UI قابل استفاده مجدد و کپسوله شده ارائه می‌دهند. در میان فناوری‌های اصلی که کامپوننت‌های وب را تشکیل می‌دهند، عناصر سفارشی (Custom Elements) به عنوان سنگ بنای تعریف تگ‌های جدید HTML با رفتار و رندرینگ سفارشی برجسته هستند. این راهنمای جامع به پیچیدگی‌های عناصر سفارشی می‌پردازد و مزایا، پیاده‌سازی و بهترین شیوه‌ها برای ساخت برنامه‌های وب مدرن را بررسی می‌کند.

کامپوننت‌های وب چه هستند؟

کامپوننت‌های وب مجموعه‌ای از استانداردهای وب هستند که به توسعه‌دهندگان اجازه می‌دهند عناصر HTML قابل استفاده مجدد، کپسوله شده و تعامل‌پذیر ایجاد کنند. آنها رویکردی ماژولار به توسعه وب ارائه می‌دهند و امکان ایجاد کامپوننت‌های UI سفارشی را فراهم می‌کنند که می‌توانند به راحتی در پروژه‌ها و فریمورک‌های مختلف به اشتراک گذاشته و استفاده شوند. فناوری‌های اصلی پشت کامپوننت‌های وب عبارتند از:

درک عناصر سفارشی

عناصر سفارشی در قلب کامپوننت‌های وب قرار دارند و به توسعه‌دهندگان امکان می‌دهند تا واژگان HTML را با عناصر خود گسترش دهند. این عناصر سفارشی مانند عناصر استاندارد HTML رفتار می‌کنند، اما می‌توانند برای نیازهای خاص برنامه سفارشی‌سازی شوند و انعطاف‌پذیری و سازماندهی کد بیشتری را فراهم کنند.

تعریف عناصر سفارشی

برای تعریف یک عنصر سفارشی، باید از متد customElements.define() استفاده کنید. این متد دو آرگومان می‌گیرد:

  1. نام عنصر: یک رشته که نام عنصر سفارشی را نشان می‌دهد. نام باید حاوی یک خط تیره (-) باشد تا از تداخل با عناصر استاندارد HTML جلوگیری شود. به عنوان مثال، my-element یک نام معتبر است، در حالی که myelement معتبر نیست.
  2. کلاس عنصر: یک کلاس جاوا اسکریپت که HTMLElement را توسعه می‌دهد و رفتار عنصر سفارشی را تعریف می‌کند.

در اینجا یک مثال ساده آورده شده است:

class MyElement extends HTMLElement {
  constructor() {
    super();
    this.innerHTML = 'سلام، دنیا!';
  }
}

customElements.define('my-element', MyElement);

در این مثال، ما یک عنصر سفارشی به نام my-element تعریف می‌کنیم. کلاس MyElement کلاس HTMLElement را توسعه می‌دهد و در سازنده (constructor)، محتوای HTML داخلی عنصر را به "سلام، دنیا!" تنظیم می‌کند.

متدهای بازگشتی چرخه حیات عنصر سفارشی

عناصر سفارشی چندین متد بازگشتی چرخه حیات (lifecycle callbacks) دارند که به شما امکان می‌دهند کد را در مراحل مختلف چرخه حیات عنصر اجرا کنید. این متدهای بازگشتی فرصت‌هایی برای مقداردهی اولیه عنصر، پاسخ به تغییرات ویژگی‌ها (attributes) و پاک‌سازی منابع هنگام حذف عنصر از DOM فراهم می‌کنند.

در اینجا مثالی است که استفاده از متدهای بازگشتی چرخه حیات را نشان می‌دهد:

class MyElement extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({mode: 'open'});
  }

  connectedCallback() {
    this.shadow.innerHTML = `

به DOM متصل شد!

`; console.log('عنصر متصل شد'); } disconnectedCallback() { console.log('عنصر قطع شد'); } static get observedAttributes() { return ['data-message']; } attributeChangedCallback(name, oldValue, newValue) { if (name === 'data-message') { this.shadow.innerHTML = `

${newValue}

`; } } } customElements.define('my-element', MyElement);

در این مثال، connectedCallback() یک پیام را در کنسول ثبت می‌کند و محتوای HTML داخلی عنصر را هنگام اتصال به DOM تنظیم می‌کند. disconnectedCallback() پیامی را هنگام قطع شدن عنصر ثبت می‌کند. attributeChangedCallback() زمانی فراخوانی می‌شود که ویژگی data-message تغییر کند و محتوای عنصر را بر اساس آن به‌روز می‌کند. getter observedAttributes مشخص می‌کند که ما می‌خواهیم تغییرات ویژگی data-message را مشاهده کنیم.

استفاده از Shadow DOM برای کپسوله‌سازی

Shadow DOM برای کامپوننت‌های وب کپسوله‌سازی فراهم می‌کند و به شما امکان می‌دهد یک درخت DOM جداگانه برای یک کامپوننت ایجاد کنید که از بقیه صفحه جدا شده است. این بدان معناست که استایل‌ها و اسکریپت‌های تعریف شده در Shadow DOM بر بقیه صفحه تأثیر نمی‌گذارند و بالعکس. این کپسوله‌سازی به جلوگیری از تداخلات کمک می‌کند و تضمین می‌کند که کامپوننت‌های شما به طور قابل پیش‌بینی رفتار می‌کنند.

برای استفاده از Shadow DOM، می‌توانید متد attachShadow() را روی عنصر فراخوانی کنید. این متد یک شیء گزینه‌ها می‌گیرد که حالت (mode) Shadow DOM را مشخص می‌کند. mode می‌تواند 'open' یا 'closed' باشد. اگر حالت 'open' باشد، Shadow DOM از طریق جاوا اسکریپت با استفاده از ویژگی shadowRoot عنصر قابل دسترسی است. اگر حالت 'closed' باشد، Shadow DOM از جاوا اسکریپت قابل دسترسی نیست.

در اینجا مثالی است که استفاده از Shadow DOM را نشان می‌دهد:

class MyElement extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: 'open' });
    this.shadow.innerHTML = `
      
      

این در داخل Shadow DOM است.

`; } } customElements.define('my-element', MyElement);

در این مثال، ما یک Shadow DOM با mode: 'open' به عنصر متصل می‌کنیم. سپس محتوای HTML داخلی Shadow DOM را طوری تنظیم می‌کنیم که شامل یک استایل باشد که رنگ پاراگراف‌ها را آبی می‌کند و یک عنصر پاراگراف با مقداری متن. استایل تعریف شده در Shadow DOM فقط برای عناصر داخل Shadow DOM اعمال می‌شود و بر پاراگراف‌های خارج از Shadow DOM تأثیر نخواهد گذاشت.

مزایای استفاده از عناصر سفارشی

عناصر سفارشی چندین مزیت برای توسعه وب ارائه می‌دهند:

مثال‌های عملی از عناصر سفارشی

بیایید چند مثال عملی از نحوه استفاده از عناصر سفارشی برای ساخت کامپوننت‌های UI متداول را بررسی کنیم.

یک کامپوننت شمارنده ساده

این مثال نشان می‌دهد که چگونه می‌توان یک کامپوننت شمارنده ساده با استفاده از عناصر سفارشی ایجاد کرد.

class Counter extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: 'open' });
    this._count = 0;
    this.render();
  }

  connectedCallback() {
    this.shadow.querySelector('.increment').addEventListener('click', () => {
      this.increment();
    });
    this.shadow.querySelector('.decrement').addEventListener('click', () => {
      this.decrement();
    });
  }

  increment() {
    this._count++;
    this.render();
  }

  decrement() {
    this._count--;
    this.render();
  }

  render() {
    this.shadow.innerHTML = `
      
      
${this._count}
`; } } customElements.define('my-counter', Counter);

این کد یک کلاس Counter را تعریف می‌کند که HTMLElement را توسعه می‌دهد. سازنده (constructor) کامپوننت را مقداردهی اولیه می‌کند، یک Shadow DOM متصل می‌کند و شمارش اولیه را روی 0 تنظیم می‌کند. متد connectedCallback() شنوندگان رویداد را به دکمه‌های افزایش و کاهش اضافه می‌کند. متدهای increment() و decrement() شمارش را به‌روز می‌کنند و متد render() را برای به‌روزرسانی رندرینگ کامپوننت فراخوانی می‌کنند. متد render() محتوای HTML داخلی Shadow DOM را برای شامل کردن نمایشگر شمارنده و دکمه‌ها تنظیم می‌کند.

یک کامپوننت کروسل تصویر

این مثال نشان می‌دهد که چگونه می‌توان یک کامپوننت کروسل تصویر با استفاده از عناصر سفارشی ایجاد کرد. برای اختصار، منابع تصویر متغیرهای جایگزین هستند و می‌توانند به صورت پویا از یک API، یک CMS یا حافظه محلی بارگیری شوند. استایل‌دهی نیز به حداقل رسیده است.

class ImageCarousel extends HTMLElement {
 constructor() {
  super();
  this.shadow = this.attachShadow({ mode: 'open' });
  this._images = [
  'https://via.placeholder.com/350x150',
  'https://via.placeholder.com/350x150/0077bb',
  'https://via.placeholder.com/350x150/00bb77',
  ];
  this._currentIndex = 0;
  this.render();
 }

 connectedCallback() {
  this.shadow.querySelector('.prev').addEventListener('click', () => {
  this.prevImage();
  });
  this.shadow.querySelector('.next').addEventListener('click', () => {
  this.nextImage();
  });
 }

 nextImage() {
  this._currentIndex = (this._currentIndex + 1) % this._images.length;
  this.render();
 }

 prevImage() {
  this._currentIndex = (this._currentIndex - 1 + this._images.length) % this._images.length;
  this.render();
 }

 render() {
  this.shadow.innerHTML = `
  
  
  `;
 }
}

customElements.define('image-carousel', ImageCarousel);

این کد یک کلاس ImageCarousel را تعریف می‌کند که HTMLElement را توسعه می‌دهد. سازنده کامپوننت را مقداردهی اولیه می‌کند، یک Shadow DOM متصل می‌کند و آرایه تصاویر اولیه و شاخص فعلی را تنظیم می‌کند. متد connectedCallback() شنوندگان رویداد را به دکمه‌های قبلی و بعدی اضافه می‌کند. متدهای nextImage() و prevImage() شاخص فعلی را به‌روز می‌کنند و متد render() را برای به‌روزرسانی رندرینگ کامپوننت فراخوانی می‌کنند. متد render() محتوای HTML داخلی Shadow DOM را برای شامل کردن تصویر فعلی و دکمه‌ها تنظیم می‌کند.

بهترین شیوه‌ها برای کار با عناصر سفارشی

در اینجا چند بهترین شیوه برای دنبال کردن هنگام کار با عناصر سفارشی آورده شده است:

عناصر سفارشی و فریمورک‌ها

عناصر سفارشی طوری طراحی شده‌اند که با سایر فناوری‌ها و فریمورک‌های وب تعامل‌پذیر باشند. آنها می‌توانند در کنار فریمورک‌های محبوبی مانند React، Angular و Vue.js استفاده شوند.

استفاده از عناصر سفارشی در React

برای استفاده از عناصر سفارشی در React، می‌توانید آنها را مانند هر عنصر HTML دیگری رندر کنید. با این حال، ممکن است نیاز به استفاده از یک ref برای دسترسی به عنصر DOM زیرین و تعامل مستقیم با آن داشته باشید.

import React, { useRef, useEffect } from 'react';

function MyComponent() {
  const myElementRef = useRef(null);

  useEffect(() => {
    if (myElementRef.current) {
      // دسترسی به API عنصر سفارشی
      myElementRef.current.addEventListener('custom-event', (event) => {
        console.log('رویداد سفارشی دریافت شد:', event.detail);
      });
    }
  }, []);

  return ;
}

export default MyComponent;

در این مثال، ما از یک ref برای دسترسی به عنصر سفارشی my-element و افزودن یک شنونده رویداد به آن استفاده می‌کنیم. این به ما امکان می‌دهد به رویدادهای سفارشی ارسال شده توسط عنصر سفارشی گوش دهیم و بر اساس آن پاسخ دهیم.

استفاده از عناصر سفارشی در Angular

برای استفاده از عناصر سفارشی در Angular، باید Angular را برای شناسایی عنصر سفارشی پیکربندی کنید. این کار را می‌توان با افزودن عنصر سفارشی به آرایه schemas در پیکربندی ماژول انجام داد.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }

پس از ثبت عنصر سفارشی، می‌توانید از آن در قالب‌های Angular خود مانند هر عنصر HTML دیگری استفاده کنید.

استفاده از عناصر سفارشی در Vue.js

Vue.js نیز به صورت بومی از عناصر سفارشی پشتیبانی می‌کند. شما می‌توانید از آنها مستقیماً در قالب‌های خود بدون هیچ پیکربندی خاصی استفاده کنید.



Vue به طور خودکار عنصر سفارشی را شناسایی کرده و آن را به درستی رندر می‌کند.

ملاحظات دسترسی‌پذیری

هنگام ساخت عناصر سفارشی، در نظر گرفتن دسترسی‌پذیری برای اطمینان از اینکه کامپوننت‌های شما برای همه، از جمله افراد دارای معلولیت، قابل استفاده هستند، بسیار مهم است. در اینجا چند ملاحظه کلیدی دسترسی‌پذیری آورده شده است:

بین‌المللی‌سازی و محلی‌سازی

هنگام توسعه عناصر سفارشی برای مخاطبان جهانی، در نظر گرفتن بین‌المللی‌سازی (i18n) و محلی‌سازی (l10n) مهم است. در اینجا چند ملاحظه کلیدی آورده شده است:

نتیجه‌گیری

عناصر سفارشی ابزاری قدرتمند برای ساخت کامپوننت‌های UI قابل استفاده مجدد و کپسوله شده هستند. آنها مزایای متعددی برای توسعه وب ارائه می‌دهند، از جمله قابلیت استفاده مجدد، کپسوله‌سازی، تعامل‌پذیری، قابلیت نگهداری و عملکرد. با پیروی از بهترین شیوه‌های ذکر شده در این راهنما، می‌توانید از عناصر سفارشی برای ساخت برنامه‌های وب مدرن که قوی، قابل نگهداری و برای مخاطبان جهانی در دسترس هستند، استفاده کنید. با ادامه تکامل استانداردهای وب، کامپوننت‌های وب، از جمله عناصر سفارشی، برای ایجاد برنامه‌های وب ماژولار و مقیاس‌پذیر اهمیت فزاینده‌ای پیدا خواهند کرد.

قدرت عناصر سفارشی را برای ساختن آینده وب، هر بار یک کامپوننت، در آغوش بگیرید. به یاد داشته باشید که دسترسی‌پذیری، بین‌المللی‌سازی و محلی‌سازی را در نظر بگیرید تا اطمینان حاصل کنید که کامپوننت‌های شما برای همه و در همه جا قابل استفاده هستند.