contenteditable: وقتی هر عنصری می‌تونه یه فیلد ویرایش‌پذیر بشه

تو فصل ۷ کامل با فرم‌ها و ورودی‌هایی مثل input و textarea آشنا شدیم که برای گرفتن متن از کاربر طراحی شده بودن. اما HTML5 یه راه دیگه هم برای ویرایش‌پذیر کردن محتوا داره که کاملاً متفاوته: ویژگی contenteditable، که می‌تونه تقریباً هر عنصر HTML رو (نه فقط input و textarea) به یه ناحیه‌ی قابل‌ویرایش تبدیل کنه.

contenteditable چیه؟

<p contenteditable="true">این متن را می‌توانید مستقیم ویرایش کنید.</p>

ویژگی contenteditable وقتی روی مقدار true تنظیم بشه، باعث می‌شه کاربر بتونه مستقیم روی همون عنصر کلیک کنه و محتواش رو مثل یه سند متنی معمولی ویرایش کنه؛ می‌تونه متن رو تایپ کنه، پاک کنه، یا حتی فرمت‌بندی‌های ساده (مثل پررنگ‌کردن با Ctrl+B) رو اعمال کنه، بدون اینکه این عنصر یه input یا textarea واقعی باشه.

تفاوت اساسی با input/textarea

یه سؤال طبیعی اینه که چرا اصلاً به این ویژگی نیاز داریم، وقتی فصل ۷ کامل input و textarea رو پوشش داد؟ تفاوت اصلی اینه: input و textarea محدود به یه فیلد فرم مشخص با محتوای متنی سادهن، اما contenteditable می‌تونه روی هر عنصر HTML (مثل یه div، p، یا حتی یه li داخل لیست) اعمال بشه و اجازه می‌ده محتوای پیچیده‌تری (شامل تگ‌های HTML دیگه، نه فقط متن ساده) داخلش ویرایش بشه.

یه مثال با محتوای غنی‌تر

<div contenteditable="true">
  <h3>یادداشت من</h3>
  <p>این یک <strong>یادداشت</strong> قابل‌ویرایش است.</p>
</div>

تو این مثال، کل این div شامل یه heading و یه پاراگراف با متن پررنگ، همگی قابل‌ویرایش هستن؛ کاربر می‌تونه مستقیم داخل این ناحیه کلیک کنه، متن رو تغییر بده، یا حتی متن جدید با فرمت‌بندی اضافه کنه. این کار با یه textarea معمولی که فقط متن خام رو قبول می‌کنه، عملاً غیرممکنه.

کاربردهای رایج contenteditable

  • ساخت ویرایشگرهای متن ساده (مثل چیزی که تو Gmail یا ابزارهای وبلاگ‌نویسی برای نوشتن متن با امکانات پررنگ/کج می‌بینی)
  • یادداشت‌برداری زنده تو یه اپلیکیشن وب
  • ویرایش سریع محتوا مستقیم تو صفحه، بدون نیاز به رفتن به یه فرم جداگانه
  • پیاده‌سازی ابزارهای همکاری تیمی (مثل ویرایش هم‌زمان یه سند)

مقدار false: غیرفعال‌کردن ویرایش

<p contenteditable="false">این متن قابل‌ویرایش نیست.</p>

می‌شه با مقدار false این قابلیت رو صریحاً غیرفعال کرد؛ این معمولاً وقتی مفیده که یه عنصر والد contenteditable="true" داره، اما می‌خوای یه بخش خاص داخلش (مثلاً یه امضای ثابت یا یه لوگو) از این قابلیت مستثنی بمونه.

<div contenteditable="true">
  <p>این بخش قابل‌ویرایش است.</p>
  <p contenteditable="false">این بخش قابل‌ویرایش نیست (مثلاً امضای ثابت).</p>
</div>

خواندن و ذخیره‌ی محتوای ویرایش‌شده با جاوااسکریپت

<div id="note" contenteditable="true">یادداشت اولیه</div>

<script>
  const note = document.getElementById("note");
  console.log(note.innerHTML); // خواندن محتوای فعلی (شامل تگ‌های HTML)
</script>

یه نکته‌ی مهم اینه که contenteditable به‌تنهایی هیچ مکانیزمی برای «ذخیره‌ی دائمی» محتوا نداره؛ اگه کاربر صفحه رو رفرش کنه، تمام تغییراتش از دست می‌ره، مگر اینکه با جاوااسکریپت این محتوا رو (مثلاً با یه درخواست به سرور یا ذخیره‌ی محلی) دستی ذخیره کنی. جزئیات این بخش، خارج از محدوده‌ی این دوره‌ی HTML5 است و به جاوااسکریپت مربوط می‌شه.

یه مثال کامل: یادداشت ساده با دکمه‌ی ذخیره

<div id="myNote" contenteditable="true">
  اینجا کلیک کن و شروع به نوشتن کن...
</div>

<button onclick="alert(document.getElementById('myNote').innerText)">
  نمایش محتوا
</button>

تو این مثال ساده، کاربر می‌تونه داخل div کلیک کنه و متن دلخواهش رو بنویسه، و با کلیک روی دکمه، محتوای فعلی (به‌صورت متن ساده، بدون تگ‌های HTML) نمایش داده می‌شه.

محدودیت مهم: contenteditable بدون کنترل دسترسی‌پذیری کافی نیست

یه نکته‌ی مهم اینه که وقتی از contenteditable استفاده می‌کنی، اون عنصر از نظر رفتاری شبیه یه فیلد فرم می‌شه، اما از نظر معنایی برای صفحه‌خوان لزوماً همون معنا رو نداره. برای دسترسی‌پذیری کامل، معمولاً باید ویژگی‌های ARIA (که تو فصل ۱۱ باهاش بیشتر آشنا می‌شیم) مثل role="textbox" رو هم اضافه کرد تا صفحه‌خوان بفهمه این یه ناحیه‌ی قابل‌ویرایشه.

<div contenteditable="true" role="textbox" aria-label="یادداشت شما">
  یادداشت اولیه
</div>

مزیت مقدار خالی contenteditable

<div contenteditable>این هم قابل‌ویرایش است.</div>

نوشتن فقط contenteditable بدون مقدار (مثل مثال بالا)، دقیقاً معادل contenteditable="true" در نظر گرفته می‌شه؛ یعنی نوشتن مقدار true اختیاریه، اما برای خوانایی بهتر کد، معمولاً توصیه می‌شه صریح نوشته بشه.

چند اشتباه رایج

  • تصور اینکه contenteditable به‌تنهایی محتوا رو دائمی ذخیره می‌کنه، بدون نیاز به کد اضافه.
  • استفاده از contenteditable بدون در نظر گرفتن دسترسی‌پذیری (مثل نبود role یا aria-label مناسب).
  • استفاده از contenteditable برای فرم‌های ساده و معمولی که input یا textarea برایشان کاملاً کافی و مناسب‌تر بود.

بهترین روش‌ها

  • برای فرم‌های ساده و معمولی، همیشه اول سراغ input یا textarea برو؛ contenteditable رو فقط برای نیازهای واقعاً پیچیده‌تر (مثل ویرایشگر متن غنی) استفاده کن.
  • همیشه یه مکانیزم ذخیره‌سازی (با جاوااسکریپت) برای محتوای ویرایش‌شده در نظر بگیر.
  • برای دسترسی‌پذیری بهتر، ویژگی‌های ARIA مناسب رو کنار contenteditable اضافه کن.

نکته‌ی سئو

محتوای contenteditable معمولاً برای بخش‌های تعاملی و پویای صفحه استفاده می‌شود که محتوایشان توسط کاربر تغییر می‌کند؛ این نوع محتوا معمولاً تأثیر مستقیمی روی سئوی صفحه‌ی اصلی ندارد، چون محتوای اولیه (قبل از ویرایش کاربر) همان چیزی است که موتورهای جستجو می‌بینند.

نکته‌ی دسترسی‌پذیری

عناصر contenteditable بدون ویژگی‌های ARIA مناسب، ممکن است برای کاربران صفحه‌خوان گیج‌کننده باشند، چون این ابزارها ممکن است نفهمند این عنصر یک ناحیه‌ی قابل‌ویرایش است؛ افزودن role="textbox" و aria-label مناسب، این وضعیت را بهبود می‌بخشد.

جمع‌بندی

ویژگی contenteditable تقریباً هر عنصر HTML را به یک ناحیه‌ی قابل‌ویرایش تبدیل می‌کند و برخلاف input/textarea، امکان ویرایش محتوای غنی‌تر (شامل تگ‌های HTML دیگر) را فراهم می‌کند. این ویژگی به‌تنهایی محتوا را ذخیره نمی‌کند و برای دسترسی‌پذیری کامل، معمولاً نیاز به ویژگی‌های ARIA اضافی دارد.