ایجاد رفتار دلخواه برای عناصر با استفاده از رجیستری‌های محدود شده

جیسون چن
Jayson Chen
پاتریک بروسه
Patrick Brosset

منتشر شده: ۹ مارس ۲۰۲۶

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

تیم مایکروسافت اج روی این ویژگی کار کرده است و ما مفتخریم اعلام کنیم که ثبت عناصر سفارشیِ محدود (scoped custom element registers) اکنون به طور پیش‌فرض از اج و کروم ۱۴۶ و همچنین سایر مرورگرهای مبتنی بر کرومیوم در دسترس هستند. اکنون می‌توانید عناصر سفارشی را کپسوله‌سازی کنید و یک مشکل دیرینه برای توسعه‌دهندگان کامپوننت‌ها و کتابخانه‌های میکرو-فرانت‌اند را حل کنید.

Browser Support

  • کروم: ۱۴۶.
  • لبه: ۱۴۶.
  • فایرفاکس: پشتیبانی نمی‌شود.
  • سافاری: ۲۶.

Source

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

دو دکمه با استایل‌های بسیار متفاوت.

رجیستری عنصر سفارشیِ محدود چیست؟

امروزه، هر تعریف عنصر سفارشی در یک صفحه وب در یک رجیستری مشترک و واحد در window.customElements قرار دارد. این بدان معناست که اگر دو کتابخانه مختلف هر دو سعی کنند یک عنصر سفارشی با نام تگ یکسان، مانند <my-button> ، تعریف کنند، خطایی رخ می‌دهد و صفحه از کار می‌افتد. این یک مشکل قابل توجه در دنیای واقعی است. برنامه‌های بزرگی که رابط‌های کاربری خود را از چندین تیم، سیستم طراحی یا میکرو-فرانت‌اند تشکیل می‌دهند، می‌توانند به راحتی با تداخل نامگذاری مواجه شوند. رجیستری‌های عنصر سفارشیِ محدود، این مشکل را با ایجاد رجیستری‌های مستقل حل می‌کنند. هر رجیستری، مجموعه تعاریف عنصر سفارشی خود را حفظ می‌کند که کاملاً از رجیستری سراسری و از یکدیگر جدا است.

ایجاد یک رجیستری جدید

به جای تعریف هر عنصر سفارشی در رجیستری سراسری window.customElements :

  1. با فراخوانی تابع new CustomElementRegistry() یک رجیستری جدید ایجاد کنید.
  2. به رجیستری جدید خود یک محدوده مشخص اختصاص دهید (به تعیین محدوده رجیستری خود مراجعه کنید).
  3. عناصری را که در رجیستری جدید قرار می‌گیرند، تعریف کنید.

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

رجیستری خود را محدود کنید

یک رجیستری عنصر سفارشی می‌تواند به یک سند، یک ریشه سایه یا یک عنصر منفرد محدود شود.

دامنه به یک ریشه سایه

برای اینکه یک رجیستری جدید به یک ریشه سایه (shadow root) محدود شود، هنگام فراخوانی متد attachShadow() از گزینه customElementRegistry استفاده کنید. اکنون تمام عناصر سفارشی که درون آن ریشه سایه قرار دارند، از تعریفی که در رجیستری محدود شده مربوطه وجود دارد، استفاده خواهند کرد:

// Create your custom registry.
const registry = new CustomElementRegistry();
// Define a custom element in the new registry.
registry.define('my-card', class extends HTMLElement {
  connectedCallback() {
    this.textContent = 'Hello from scoped registry!';
  }
});

// Create shadow root, providing it with your new custom element registry.
const host = document.querySelector('#host');
const shadow = host.attachShadow({
  mode: 'open',
  customElementRegistry: registry,
});

shadow.innerHTML = '<my-card></my-card>';

DOM سایه اعلانی

از ویژگی shadowrootcustomelementregistry روی یک عنصر <template> استفاده کنید تا به مرورگر بگویید که ریشه سایه حاصل از یک رجیستری محدود به دامنه به جای رجیستری سراسری استفاده می‌کند:

<my-host>
  <template shadowrootmode="open" shadowrootcustomelementregistry>
    <my-widget></my-widget>
  </template>
</my-host>
  const registry = new CustomElementRegistry();
  registry.define('my-widget', class extends HTMLElement {
    connectedCallback() { this.textContent = 'Scoped!'; }
  });

  const shadow = document.querySelector('my-host').shadowRoot;
  registry.initialize(shadow);

همانطور که در مثال نشان داده شده است، این ویژگی فضایی را برای رجیستری عنصر سفارشی رزرو می‌کند و کاربر باید رجیستری را در ریشه سایه تعریف و مقداردهی اولیه کند. هدف‌گیری به یک سند غیرمتصل

همچنین می‌توانید یک رجیستری را به یک سند، مانند سندی که توسط document.implementation.createHTMLDocument() ایجاد شده است، محدود کنید. این به شما امکان می‌دهد عناصر <template> را کپی کنید و دستکاری سند خارج از صفحه را انجام دهید، که هر کدام مجموعه‌های جداگانه‌ای از تعاریف مؤلفه خود را دارند. برای انجام این کار، از متد CustomElementRegistry.initialize() استفاده کنید:

// Create a new registry.
const registry = new CustomElementRegistry();
registry.define('app-widget', AppWidget);

// Create a document, and use registry.initialize() to scope the registry to the document.
const doc = document.implementation.createHTMLDocument('');
registry.initialize(doc);

doc.body.innerHTML = '<app-widget></app-widget>';

دامنه به یک عنصر منفرد

همچنین می‌توانید با ارسال گزینه customElementRegistry به document.createElement() یک رجیستری را مستقیماً به یک عنصر و زیردرخت آن مرتبط کنید. عنصر و فرزندان آن، صرف نظر از اینکه بعداً در کدام بخش از DOM قرار داده شوند، در برابر آن رجیستری قرار می‌گیرند:

// Create a registry and define a custom element in it.
const registry = new CustomElementRegistry();
registry.define('fancy-label', FancyLabel);

// Create a new DOM element and scope the new registry to it.
const el = document.createElement('fancy-input', {
  customElementRegistry: registry,
});

// Use a custom element in the new DOM element.
el.innerHTML = '<fancy-label>Name</fancy-label>';

بیشتر بدانید

برای کسب اطلاعات بیشتر، نسخه آزمایشی Edge و کد منبع آن را بررسی کنید و مقاله مرجع CustomElementRegistry از MDN را بخوانید.

به لطف همکاری ما از طریق پروژه کرومیوم، ثبت عناصر سفارشی محدود (scoped) اکنون به طور پیش‌فرض در مایکروسافت اج و کروم و همچنین در سایر مرورگرهای مبتنی بر کرومیوم فعال شده‌اند.

نیازی به فعال کردن هیچ تنظیماتی یا ثبت نام در نسخه آزمایشی اصلی نیست. می‌توانید همین امروز از این ویژگی در مرورگرهای مبتنی بر کرومیوم استفاده کنید.

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

اگر در پیاده‌سازی این ویژگی در مرورگر مبتنی بر کرومیوم باگی پیدا کردید، می‌توانید مشکل را در crbug.com/new برای ما مطرح کنید تا بررسی کنیم.

ما امیدواریم که ثبت عناصر سفارشیِ دارای محدوده، استفاده از اجزای وب را آسان‌تر کند.