تغییر محتوا و Attributeهای یک عنصر

مقدمه

در درس قبل یاد گرفتیم چگونه عنصر جدید بسازیم و آن را به DOM اضافه کنیم. اما اغلب اوقات، به‌جای ساختن عنصر تازه، فقط نیاز داریم محتوای یک عنصر موجود را تغییر دهیم، یا Attribute های آن (مثل src، href یا data-*) را بخوانیم و ویرایش کنیم. در این درس، ابزارهای اصلی این کار را بررسی می‌کنیم.

textContent — خواندن و نوشتن متن خام

textContent ساده‌ترین راه برای خواندن یا تغییر متن داخل یک عنصر است:

خواندن و تغییر textContent
خروجی کنسول اینجا نمایش داده می‌شود...

تحلیل کد

نکته‌ی مهم درباره‌ی textContent این است که هر مقداری که به آن نسبت دهیم، به‌صورت متن خام (Plain Text) تفسیر می‌شود؛ حتی اگر آن مقدار شامل تگ‌های HTML باشد:

title.textContent = "<strong>متن پررنگ</strong>";
// نتیجه: خودِ تگ‌ها به‌صورت متن ساده نمایش داده می‌شوند، نه اجرا می‌شوند

innerHTML — خواندن و نوشتن با تفسیر HTML

برخلاف textContent، مقداری که به innerHTML نسبت داده می‌شود، به‌عنوان کد HTML واقعی تفسیر و اجرا می‌شود:

استفاده از innerHTML برای افزودن ساختار HTML
خروجی کنسول اینجا نمایش داده می‌شود...

تحلیل رفتار جاوااسکریپت

در این مثال، برخلاف textContent، تگ strong واقعاً به‌عنوان یک عنصر HTML تفسیر می‌شود و متن داخل آن به‌صورت پررنگ نمایش داده می‌شود. این قدرت اضافه، اما یک خطر جدی هم به همراه دارد: اگر مقداری که به innerHTML نسبت می‌دهیم از یک منبع غیرقابل‌اعتماد (مثلاً ورودی مستقیم کاربر) گرفته شده باشد، این کار می‌تواند راه را برای اجرای کد مخرب باز کند؛ حمله‌ای که تحت عنوان DOM XSS در فصل Security این دوره به‌طور کامل بررسی خواهد شد. به همین دلیل، وقتی صرفاً قصد نمایش متن داریم (بدون نیاز به ساختار HTML)، textContent همیشه انتخاب امن‌تری است.

getAttribute و setAttribute — کار عمومی با Attribute ها

برای خواندن یا تنظیم هر Attribute دلخواه HTML (مثل src، href، title یا Attribute های سفارشی)، از getAttribute و setAttribute استفاده می‌کنیم:

خواندن و تنظیم Attribute با getAttribute/setAttribute
خروجی کنسول اینجا نمایش داده می‌شود...

دسترسی مستقیم به Attribute های رایج به‌عنوان Property

برای بسیاری از Attribute های رایج، جاوااسکریپت امکان دسترسی مستقیم به‌عنوان Property را هم فراهم می‌کند؛ بدون نیاز به getAttribute/setAttribute:

let image = document.getElementById("logo");

console.log(image.src); // مستقیماً به‌عنوان Property
image.src = "new-logo.png";
image.alt = "لوگوی جدید";

برای Attribute های استاندارد و شناخته‌شده (مثل src، href، id، value)، هر دو روش معمولاً نتیجه‌ی یکسانی می‌دهند و انتخاب بین آن‌ها بیشتر یک سلیقه است. اما برای Attribute های سفارشی یا کمتر رایج، دسترسی مستقیم به‌عنوان Property همیشه ممکن نیست؛ در چنین مواردی، getAttribute/setAttribute گزینه‌ی قابل‌اعتمادتری است.

Data Attributes — ذخیره‌ی داده‌ی سفارشی روی عنصر

یکی از رایج‌ترین کاربردهای setAttribute/getAttribute، کار با Data Attributes است؛ Attribute هایی که با پیشوند data- در HTML نوشته می‌شوند و برای نگه‌داری داده‌ی سفارشی مرتبط با یک عنصر طراحی شده‌اند:

<li data-user-id="42" data-role="admin">علی</li>
کار با Data Attributes از طریق dataset
خروجی کنسول اینجا نمایش داده می‌شود...

تحلیل کد

Property ویژه‌ی dataset دسترسی راحت‌تری به تمام data-* Attribute های یک عنصر فراهم می‌کند؛ نام Attribute بدون پیشوند data- و به‌صورت camelCase نوشته می‌شود (برای نمونه، data-user-id به dataset.userId تبدیل می‌شود). این روش، خواناتر و رایج‌تر از استفاده‌ی مستقیم getAttribute("data-user-id") است.

hasAttribute و removeAttribute

برای بررسی وجود یک Attribute یا حذف کامل آن، به‌ترتیب از hasAttribute و removeAttribute استفاده می‌کنیم:

let link = document.querySelector("a");

console.log(link.hasAttribute("target")); // true یا false

link.removeAttribute("target");
console.log(link.hasAttribute("target")); // false

جدول جمع‌بندی

ابزارکاربرد
textContentخواندن/نوشتن متن خام (امن در برابر تفسیر HTML)
innerHTMLخواندن/نوشتن با تفسیر کامل HTML (نیازمند احتیاط امنیتی)
getAttribute / setAttributeکار عمومی با هر Attribute
datasetدسترسی راحت به Data Attributes (data-*)
hasAttribute / removeAttributeبررسی وجود یا حذف کامل یک Attribute

جمع‌بندی

برای تغییر محتوای متنی یک عنصر، textContent گزینه‌ی امن و ساده است، درحالی‌که innerHTML امکان تفسیر کامل HTML را می‌دهد اما باید با احتیاط امنیتی استفاده شود. برای کار با Attribute ها، getAttribute/setAttribute روشی عمومی است و برای Data Attributes، Property ویژه‌ی dataset دسترسی خواناتری فراهم می‌کند.