در این مقاله در مورد DOM (Document Object Model) و نحوه دستکاری آن (DOM Manipulation) توسط جاوااسکریپت صحبت میکنیم.
لغت DOM مخفف Document Object Model (مدل شیءِ سند) میباشد. در تعریف DOM میتوان گفت که یک ارائه اطلاعات از اشیائی است که ساختار و محتوای یک صفحه وب را مشخص میکند.
برای فهمیدن دقیق DOM، باید اول بفهمیم چگونه یک سند HTML به یک صفحه وب قابل تعامل تبدیل میشود. مسیری که در این تبدیل اتفاق میافتد به عنوان "مسیر تفسیر اساسی (Critical Rendering Path)" شناخته میشود.
مراحل موجود در این مسیر به طور اصلی به دو بخش تقسیم میشود. بخش اول، مشخص کردن چیزهایی که تفسیر میشود و بخش دوم، تفسیر آنها در مرورگر است. یک جزء مهم که در بین این دو بخش تشکیل میشود، "درخت تفسیر (Render Tree)" است.
ساختار DOM با استفاده از چیزی که ما آن را "درخت گره (node tree)" مینامیم نمایش داده میشود. در درخت گره، عنصر h گرهی منشاء است که توسط شاخههایی که شامل عناصر فرزند است ادامه پیدا میکند. این درخت تا جایی که عنصری وجود داشته باشد که فرزندی ندارد، ادامه پیدا میکند.
برای فهم بهتر مثال زیر را در نظر بگیرید:
این سند HTML را میتوان به صورت درخت گرهی زیر نمایش داد:
چند نکته در مورد DOM که باید در نظر بگیریم:
مثال:
سند بالا غیر معتبر است به دلیل اینکه تگهای <head> و <body> در آن وجود ندارد، ولی درخت DOM به صورت زیر تشکیل میشود:
2. DOM به عنوان یک منبع زنده عمل میکند و یه کمک جاوااسکریپت میتوان آن را دستکاری کرد. هر زمان که تغییری در DOM رخ دهد، مرورگر DOM را دوباره تفسیر (re-render) میکند.
مثال:
حال با استفاده از جاوااسکریپت DOM را دستکاری میکنیم و یک پارگراف دیگر با متن "This is paragraph 2" به آن اضافه میکنیم:
بعد از اضافه کردن اسکریپت به سند HTML :
خروجی مرورگر به این صورت است:
3. چیزی که ما در مرورگر میبینیم درخت تفسیر است و نه خود DOM
مرورگر پنجره نمایش (viewport) خود را با کمک درخت تفسیر، تشکیل میدهند. درخت تفسیر ترکیبی از DOM و CSSOM (CSS Object Model) است. تفاوت بین درخت تفسیر و DOM در این است که درخت تفسیر فقط شامل چیزهایی است که میتواند در صفحه نمایش داده شوند است و تمام چیزهایی که با استفاده از CSS مخفی شده ار آن کم میشود.
در مثال زیر ما به عنصر p استایل display: none را دادهایم:
از آنجایی که تگ <p> جزوی از سند HTML است، داخل درخت DOM قرار خواهد گرفت:
ولی زمانی که درخت تفسیر در حال تشکیل است، DOM و CSSOM را با هم در نظر میگیرد و از آنجایی که عنصر p دارای استایلی است که از نمایش آن جلوگیری میکند، پس از درخت تفسیر حذف میشود.
دستکاری DOM، تعامل با DOM API برای تغییر یا تصحیح سند HTML است که میخواهد بر روی مرورگر وب تفسیر (Render) شود. سند HTML میتواند به گونهای دستکاری شود که عنصری به آن اضافه یا کم شود، تغییر یابد، جا به جا شود و ... .
با دستکاری DOM میتوان برنامهای درست کرد که بدون تازهسازی (refresh)، بروزرسانی شود. میتوان عناصر موجود در سند را جابهجا، ترکیب یا حذف کرد.
از زبانهای زیادی برای دستکاری DOM میتوان استفاده کرد که مهمترین آنها جاوااسکریپت است. به عنوان مثال، سند HTML زیر را در نظر بگیرید:
برای دستکاری یک عنصر داخل DOM، در ابتدا باید آن عنصر را انتخاب کرده و ارجاع (reference) به آن را در داخل یک متغیر ذخیره کنید. این کار را میتوان با Query Selectors انجام داد:
تابع querySelector یک رفرنس از اولین مورد مطابق با انتخابکننده (selector) 'p' را برمیگرداند. تابع querySelectorAll یک لیست گره شمال تمامی رفرنسهای مطابق با (selector) 'p' را برمیگرداند.
توجه داشته باشید که querySelectorAll یک لیست گره را برمیگرداند و نه یک آرایه. لیست گره شبیه به آرایه است و تا قسمتی شبیه به آرایه عمل میکند ولی همه متدهایی که برروی آرایه اعمال میشود را نمیتوان برروی لیست گره نیز اعمال کرد.
با استفاده از id، tag و class نیز میتوان یک عنصر را انتخاب کرد:
ساخت یک عنصر و دستکاری DOM :
در بالا، عنصر section را انتخاب کردیم، حال یک عنصر p میسازیم:
در بالا یک عنصر پاراگراف را با استفاده از متد createElement ساختیم. در ادامه یک متن نیز با استفاده از textContent به آن اضافه کردیم.
حال میتوان عنصر newPara را با استفاده از متد appendChild به آخر عنصر section اضافه کرد:
حال بیاید یک متن جدید به پاراگراف اضافه کنیم. این کار را با متد createTextNode انجام میدهیم و سپس با appendChild آنرا به عنصر newPara اضافه میکنیم:
با دستکاری DOM حذف کردن یک عنصر از آن نیز ممکن است. عنصر newPara را میتوان به دو روش حذف کرد:
در روش اول، از متد removeChild استفاده میکنیم. برای استفاده از این متد باید گره مادر بشناسیم و این متد را بر روی آن اعمال کنیم:
عنصر sect، گرهی مادر گرهی newPara است. بدین ترتیب ما newPara با حذف کردن گرهی فرزند sect، حذف میکنیم.
در روش دوم، از متد remove استفاده میکنیم. این متد زمانی استفاده میشود که بخواهیم بر پایه ارجاع به خود عنصر، آن را حذف کنیم:
توجه داشته باشید که متد remove در مروگرهای قدیمی پشتیبانی نمیشود و برای اجرای کد بالا باید این کار را کنیم:
در ادامه بیاید یک event listener به عنصر button برای نمایش پیام d، زمانی بر روی button کلیک میشود، اضافه کنیم. این کار را میتوان با استفاده از متد addEventListener انجام داد. این متد دو پارامتر دارد. پارامتر اول نوع ایونت است مانند click و پارامتر دوم تابعی است که، به هنگام رخ دادن ایونت، میخواهیم اجرا شود:
کد بالا را به صورت زیر نیز میتوان نوشت:
میتوانیم یک سری ویژگیها را برای آپدیت مستقیم عناصر، اعمال کنیم. اعمال استایلهایی بر روی عنصر newPara:
اگر با استفاده از inspector مرورگر کد HTML را چک کنید میبینید که این استایلها به صورت inline به عنصر newPara اضافه شده:
با دستکاری DOM میتوان خاصیت (attribute) هم به عناصر اصافه کرد. این کار با متد setAttribute میتوان انجام داد. این متد دو پارامتر دارد، پارامتر اول خاصیتی که میخواهید اضافه کنید و پارامتر دوم، عنصری که میخواهید این خاصیت را بر روی آن اعمال کنید:
ویژگیها و متدهای بسیاری را میتوان با دستکاری DOM اعمال کرد. برای مطالعه بیشتر میتوانید به سایت w3scools یا MDN مراجعه کنید.
ترجمهای از مقالات What is DOM و What Is DOM Manipulation