مقدمه
یک `Range` یا «محدوده» در DOM، یک قطعه یا بخشی از یک سند را نشان میدهد. این قطعه میتواند شامل
گرههای متنی و عنصری باشد. به عبارت سادهتر، یک `Range` معادل برنامهنویسی عملیاتی است که کاربر
با ماوس برای انتخاب (select) بخشی از متن و محتوای صفحه انجام میدهد. این قابلیت، یک API قدرتمند
برای دستکاریهای دقیق روی بخشهای خاصی از سند، مانند هایلایت کردن نتایج جستجو، استخراج بخشی از
محتوا، یا پیادهسازی ویرایشگرهای متن پیشرفته (Rich Text Editors) فراهم میکند.
ایجاد و تعریف یک Range
برای کار با یک محدوده، ابتدا باید یک شیء Range ایجاد کنیم. این کار با استفاده از متد document.createRange() انجام میشود. پس از ایجاد، شیء Range هنوز
به هیچ بخشی از سند اشاره نمیکند و باید نقاط شروع و پایان آن را مشخص کنیم.
- setStart(node, offset): نقطه شروع محدوده را تعیین میکند.
آرگومان اول گره شروع و آرگومان دوم (offset) یک عدد است که برای گرههای متنی، شماره
کاراکتر و برای گرههای عنصری، شماره ایندکس فرزند را مشخص میکند.
- setEnd(node, offset): نقطه پایان محدوده را به روشی مشابه تعیین
میکند.
- selectNode(node): یک روش سادهتر که کل یک گره (شامل خود گره و
تمام محتوایش) را انتخاب میکند.
- selectNodeContents(node): فقط محتوای داخل یک گره را
انتخاب میکند.
JAVASCRIPT
const p = document.getElementById('myPara');
const textNode = p.firstChild;
const range = document.createRange();
range.setStart(textNode, 8);
range.setEnd(textNode, 12);
در این کد، یک شیء Range ساختهایم که به صورت منطقی کلمه some را در گره متنی پاراگراف
نمایندگی میکند. این محدوده هنوز هیچ تأثیر بصری روی صفحه ندارد.
دستکاری محتوای داخل Range
قدرت واقعی Range در متدهایی است که به ما اجازه میدهند محتوای انتخاب شده را دستکاری کنیم.
حذف و استخراج محتوا
دو متد اصلی برای حذف محتوای یک محدوده وجود دارد:
- deleteContents(): محتوای داخل محدوده را از سند حذف میکند.
- extractContents(): محتوای داخل محدوده را از سند حذف کرده و آن
را به صورت یک DocumentFragment برمیگرداند تا بتوانیم از آن در جای دیگری استفاده کنیم.
احاطه کردن محتوا
یکی از رایجترین کاربردهای Range، احاطه کردن یا پیچیدن (wrap) محتوای انتخاب شده با یک عنصر
جدید است. این کار برای هایلایت کردن متن یا تبدیل بخشی از متن به لینک ایدهآل است.
- surroundContents(newNode): محتوای محدوده را با گره جدیدی که به
عنوان آرگومان داده شده (newNode) احاطه میکند. این گره جدید جای محتوای انتخاب شده را
در درخت DOM میگیرد و محتوای انتخاب شده به فرزند آن تبدیل میشود.
JAVASCRIPT
const p = document.getElementById('myPara');
const textNode = p.firstChild;
const range = document.createRange();
range.setStart(textNode, 13);
range.setEnd(textNode, 20);
const highlightSpan = document.createElement('span');
highlightSpan.style.backgroundColor = 'yellow';
try {
range.surroundContents(highlightSpan);
} catch(e) {
console.error("Could not surround contents: ", e);
}
در این مثال کلاسیک، ابتدا محدودهای را تعریف میکنیم که کلمه example را در بر میگیرد.
سپس یک عنصر <span> با پسزمینه زرد ایجاد میکنیم. در نهایت، با فراخوانی surroundContents()، متن انتخاب شده را داخل این <span> قرار
میدهیم و به این ترتیب آن را هایلایت میکنیم.
متد surroundContents() در صورتی که محدوده انتخاب شده شامل بخشی از
یک گره باشد (و نه کل آن)، یا اگر گرههای ابتدا و انتهای آن در یک سطح نباشند، ممکن است با خطا
مواجه شود. به همین دلیل بهتر است آن را داخل یک بلاک try...catch قرار دهیم.
مفهوم `Ranges` ابزاری دقیق برای کار با بخشهای دلخواه سند در اختیار ما قرار داد. با استفاده از
آن میتوانیم بخشهایی از محتوا را به صورت برنامهنویسی انتخاب کرده و عملیاتی مانند حذف، استخراج،
یا احاطه کردن را روی آن انجام دهیم. در درس پایانی این فصل، با دستهای از APIهای مدرن و قدرتمند
به نام `Observable APIs` آشنا خواهیم شد. این APIها به ما اجازه میدهند تا تغییرات در DOM را به
صورت کارآمد و واکنشی مشاهده و رهگیری کنیم.