۲۵ آوریل ۲۰۲۵

Template element (عنصر قالب)

عنصر داخلی <template> به عنوان محلی برای ذخیره‌ی قالب‌های نشانه‌گذاری HTML استفاده می‌شود. مرورگر محتوای آن را نادیده می‌گیرد و تنها اعتبار نحوی آن را بررسی می‌کند، اما ما می‌توانیم با استفاده از JavaScript به آن دسترسی پیدا کنیم و برای ساخت سایر عناصر از آن استفاده کنیم. در تئوری، می‌توانیم هر عنصر نامرئی دیگری را در HTML برای ذخیره‌ی کد HTML قرار دهیم. پس چه چیزی <template> را خاص می‌کند؟ اول از همه، محتوای آن می‌تواند هر HTML معتبری باشد، حتی اگر معمولاً نیاز به یک تگ محاط‌کننده داشته باشد. برای مثال، می‌توانیم یک ردیف جدول <tr>را داخل آن قرار دهیم:

<template>
  <tr>
    <td>Contents</td>
  </tr>
</template>

معمولاً اگر سعی کنیم تگ <tr> را داخل مثلاً یک <div> قرار دهیم، مرورگر ساختار نامعتبر DOM را تشخیص می‌دهد و آن را “اصلاح” می‌کند؛ یعنی به‌طور خودکار یک <table> به اطراف آن اضافه می‌کند. اما این چیزی نیست که ما بخواهیم. در عوض، <template> دقیقاً همان چیزی را که درونش قرار می‌دهیم، بدون تغییر نگه می‌دارد.

ما حتی می‌توانیم استایل‌ها و اسکریپت‌ها را نیز داخل <template> قرار دهیم:

<template>
  <style>
    p { font-weight: bold; }
  </style>
  <script>
    alert("Hello");
  </script>
</template>

مرورگر محتوای درون <template> را «خارج از سند» در نظر می‌گیرد: استایل‌ها اعمال نمی‌شوند، اسکریپت‌ها اجرا نمی‌شوند، تگ <video autoplay> پخش نمی‌شود و غیره.

وقتی این محتوا را وارد سند (document) کنیم، فعال می‌شود (استایل‌ها اعمال می‌شوند، اسکریپت‌ها اجرا می‌شوند و غیره).

وارد کردن template

محتوای یک template از طریق ویژگی content آن در دسترس است که یک DocumentFragment محسوب می‌شود — نوع خاصی از گره DOM.

می‌توانیم با آن مانند هر گره‌ی دیگری از DOM رفتار کنیم، با یک تفاوت خاص: زمانی که آن را در جایی قرار می‌دهیم، فقط فرزندانش وارد سند می‌شوند، نه خود DocumentFragment.

برای مثال:

<template id="tmpl">
  <script>
    alert("Hello");
  </script>
  <div class="message">Hello, world!</div>
</template>

<script>
  let elem = document.createElement('div');

  // Clone the template content to reuse it multiple times
  elem.append(tmpl.content.cloneNode(true));

  document.body.append(elem);
  // Now the script from <template> runs
</script>

بیایید یک مثال از Shadow DOM را از فصل قبلی با استفاده از <template> بازنویسی کنیم:

<template id="tmpl">
  <style> p { font-weight: bold; } </style>
  <p id="message"></p>
</template>

<div id="elem">Click me</div>

<script>
  elem.onclick = function() {
    elem.attachShadow({mode: 'open'});

    elem.shadowRoot.append(tmpl.content.cloneNode(true)); // (*)

    elem.shadowRoot.getElementById('message').innerHTML = "Hello from the shadows!";
  };
</script>

در خط (*)، زمانی که tmpl.content را کپی کرده و درج می‌کنیم، از آنجایی که یک DocumentFragment است، فرزندان آن (یعنی <style> و <p>) به جای خودش درج می‌شوند.

این عناصر، Shadow DOM را تشکیل می‌دهند:

<div id="elem">
  #shadow-root
    <style> p { font-weight: bold; } </style>
    <p id="message"></p>
</div>

خلاصه

برای جمع‌بندی:

  • محتوای <template> می‌تواند هر HTML با ساختار نحوی صحیح باشد.
  • محتوای <template> به‌عنوان «خارج از سند» در نظر گرفته می‌شود، بنابراین روی چیزی تأثیر نمی‌گذارد.
  • ما می‌توانیم از طریق JavaScript به template.content دسترسی پیدا کنیم و با کپی کردن آن، در یک کامپوننت جدید استفاده‌اش کنیم.

تگ <template> ویژگی‌های منحصربه‌فردی دارد، زیرا:

  • مرورگر ساختار نحوی HTML داخل آن را بررسی می‌کند (برخلاف استفاده از رشته قالب درون اسکریپت).
  • …اما همچنان اجازه می‌دهد که از هر تگ HTML در سطح بالا استفاده شود، حتی تگ‌هایی که بدون تگ‌های محصورکننده منطقی نیستند (مثل <tr>).
  • وقتی محتوا وارد سند شود، تعاملی می‌شود: اسکریپت‌ها اجرا می‌شوند، ویدیوهای <video autoplay> پخش می‌شوند و غیره.

عنصر <template> به‌خودی‌خود هیچ مکانیزمی برای تکرار، اتصال داده‌ها (data binding) یا جایگزینی متغیرها ندارد، اما می‌توانیم این قابلیت‌ها را بر روی آن پیاده‌سازی کنیم.

نقشه آموزش

نظرات

قبل از نظر دادن این را بخوانید…
  • اگر پیشنهادی برای بهبود ترجمه دارید - لطفا یک ایشوی گیت‌هاب یا یک پول‌ریکوئست به جای کامنت‌گذاشتن باز کنید.
  • اگر چیزی را در مقاله متوجه نمی‌شوید – به دقت توضیح دهید.
  • برای قراردادن یک خط از کد، از تگ <code> استفاده کنید، برای چندین خط – کد را درون تگ <pre> قرار دهید، برای بیش از ده خط کد – از یک جعبهٔ شنی استفاده کنید. (plnkr، jsbin، codepen…)