سلام به شما همراهان روکسو، در این قسمت در مورد کار با DOM در جاوا اسکریپت صحبت می کنیم. این مبحث از مهم ترین و کاربردی ترین مباحث جاوا اسکریپت است چرا که استفاده تمام مواردی که آموخته ایم در DOM امکان پذیر می باشد!
پیش از رفتن به سراغ اصل مطلب بیایید یک مثال را بررسی کنیم. فرض کنید در حال تماشای تلویزیون هستید. برنامه ای را که در حال پخش است دوست ندارید و می خواهید آن را تغییر دهید. هم چنین می خواهید صدای تلویزیون را افزایش دهید.
برای انجام این کار، باید راهی برای ارتباط با تلویزیون داشته باشید. برای این کار از کنترل استفاده می کنیم. کنترل به شما امکان می دهد با تلویزیون خود ارتباط برقرار کنید. شما با کنترل، تلویزیون را فعال و پویا می کنید. به همین ترتیب، جاوا اسکریپت صفحه HTML را از طریق DOM فعال و پویا می کند. درست مانند تلویزیون که نمی تواند به تنهایی کار زیادی انجام دهد، جاوا اسکریپت هم بدون DOM نمی تواند کاری را پیش ببرد.
بنابراین برای پویایی بیشتر یک سند HTML، اسکریپت باید بتواند به محتوای سند دسترسی داشته باشد و هم چنین باید بداند کاربر چه زمانی با آن تعامل دارد. این کار را با برقراری ارتباط با مرورگر با استفاده از ویژگیها، متدها و رویدادها در رابطی به نام Document Object Model یا DOM انجام میدهد.
DOM مخفف Document Object Model است و به فارسی معنی «مدل شیء گرای سند» را می دهد. با استفاده از DOM می توانید عناصر سند HTML را تغییر داده، حذف کرده و یا ایجاد کنید!
در واقع DOM یکی از استاندارد های کنسرسیوم جهانی وب (W3C) است که استانداردی را برای دسترسی به اسناد را تعریف می کند:
The W3C Document Object Model (DOM) is a platform and language-neutral interface that allows programs and scripts to dynamically access and update the content, structure, and style of a document.
این استاندارد W3C به سه قسمت تقسیم می شود:
زمانی که صفحه وب شما بارگذاری می شود، مرورگر یک مدل شی گرا از صفحه را می سازد. در مورد زبان HTML این مدل به صورت درختی از اشیا مختلف ساخته می شود. به تصویر زیر نگاه کنید:
بر اساس همین درخت، جاوا اسکریپت می تواند به انواع عناصر HTML دسترسی پیدا کند:
این ها کارهایی هستند که DOM و جاوا اسکریپت می توانند انجام دهند و ما می خواهیم کار با آن ها را یاد بگیریم.
DOM مخفف Document Object Model است. این یک رابط برنامه نویسی است که به ما امکان ایجاد، تغییر یا حذف عناصر از سند را می دهد. هم چنین می توانیم رویدادهایی را به این عناصر اضافه کنیم تا صفحه خود را پویاتر کنیم.
DOM یک رابط برنامه نویسی برای اسناد وب است. DOM سند را به صورت گره ها و اشیا نشان می دهد. به این ترتیب، زبان های برنامه نویسی می توانند با صفحه تعامل داشته باشند. صفحه وب سندی است که می تواند در پنجره مرورگر یا به عنوان HTML نمایش داده شود. در هر دو مورد، سند یکسان است، اما DOM اجازه می دهد تا آن را دستکاری کنید. به عنوان مثال، DOM مشخص می کند که متد querySelectorAll در این قطعه کد باید فهرستی از تمام المنت های <p> در document را برگرداند:
const paragraphs = document.querySelectorAll("p"); // paragraphs[0] is the first <p> element // paragraphs[1] is the second <p> element, etc. alert(paragraphs[0].nodeName);
تمام ویژگی ها، متدها و رویدادهای موجود برای دستکاری و ایجاد صفحات وب در اشیا مدیریت می شوند. برای مثال، شی document که سند را نشان میدهد، هر شی table که رابط HTMLTableElement DOM را برای دسترسی به جداول HTML پیادهسازی میکند، و … همگی شی هستند.
DOM با استفاده از چندین API که با هم کار می کنند، ساخته شده است. هسته DOM موجودیت هایی را که هر سند و اشیا درون آن را توصیف می کنند، تعریف می کند. این در صورت نیاز توسط سایر APIها که ویژگی ها و قابلیت های جدیدی را به DOM اضافه می کنند، گسترش می یابد. به عنوان مثال، HTML DOM API پشتیبانی از نمایش اسناد HTML را به DOM اصلی اضافه می کند و API SVG پشتیبانی برای ارائه اسناد SVG را اضافه می کند.
DOM یک document را با یک درخت منطقی نشان می دهد. هر شاخه از درخت به یک گره ختم می شود و هر گره حاوی اشیا است. متدهای DOM امکان دسترسی برنامه به درخت را میدهند. با آن ها می توانید ساختار، استایل یا محتوای document را تغییر دهید.گره ها هم چنین می توانند کنترل کننده های رویداد را به گره ها متصل کنند. هنگامی که یک رویداد راه اندازی می شود، کنترل کننده های رویداد اجرا می شوند.
استانداردسازی اصلی DOM توسط کنسرسیوم وب جهانی W3C انجام شد، که آخرین نسخه اش را در سال 2004 ارائه کرد. WHATWG توسعه استاندارد را بر عهده گرفت و آن را به عنوان یک سند زنده منتشر کرد. W3C اکنون عکس های فوری پایداری از استاندارد WHATWG منتشر می کند.
نکته: DOM ساختار منطقی نامیده می شود زیرا DOM هیچ رابطه ای را بین اشیا مشخص نمی کند.
DOM راهی است برای نمایش صفحه وب به روشی سلسله مراتبی و ساختاریافته است به طوری که برنامه نویسان و کاربران آسان تر بتوانند به سند دستیابی داشته باشند و آن را دستکاری کنند. با DOM، میتوانیم به راحتی به تگها، شناسهها، کلاسها، ویژگیها یا المنت ها با استفاده از دستورات یا متدهای ارائهشده توسط شی Document دسترسی داشته باشیم و آنها را دستکاری کنیم.
تاریخچه Document Object Model با تاریخچه «جنگ مرورگرها» در اواخر دهه 1990 بین Netscape Navigator و Microsoft Internet Explorer، و هم چنین با جاوا اسکریپت که به طور گسترده در جهان پیاده سازی شدند، درهم آمیخته است.
جاوا اسکریپت توسط Netscape Communications در سال 1995 در Netscape Navigator 2.0 منتشر شد. رقیب نت اسکیپ، مایکروسافت اینترنت اکسپلورر 3.0 را در سال بعد با اجرای مجدد جاوا اسکریپت به نام JScript منتشر کرد. جاوا اسکریپت و JScript به توسعه دهندگان وب اجازه می دهند صفحات وب را با تعامل سمت مشتری ایجاد کنند. امکانات محدود برای شناسایی رویدادهای تولید شده توسط کاربر و اصلاح سند HTML در نسل اول این زبان ها در نهایت به "DOM Level 0" یا " Legacy DOM " معروف شد. هیچ استاندارد مستقلی برای DOM Level 0 ایجاد نشده است، اما تا حدی در مشخصات HTML 4 مشخص شده است.
DOM قدیمی دارای دسترسی محدود بود. المنت های فرم، link و تصویر را می توان با یک نام سلسله مراتبی که با شی سند root شروع می شود ارجاع داد. یک نام سلسله مراتبی می تواند از نام ها یا اندیس های ترتیبی عناصر پیموده شده استفاده کند. به عنوان مثال، یک عنصر ورودی فرم می تواند با استفاده از document.formName.inputName یا document.forms[0].elements[0] قابل دسترسی باشد.
در سال 1997، نت اسکیپ و مایکروسافت به ترتیب نسخه 4.0 Netscape Navigator و Internet Explorer را منتشر کردند و از قابلیت Dynamic HTML (DHTML) پشتیبانی کردند که امکان تغییر در یک سند HTML بارگذاری شده را فراهم می کرد. DHTML نیاز به پسوندهایی برای شی سند ابتدایی دارد که در اجرای Legacy DOM موجود بود. اگرچه پیادهسازیهای Legacy DOM تا حد زیادی با هم سازگار بودند، زیرا JScript مبتنی بر جاوا اسکریپت بود، پسوندهای DHTML DOM بهطور موازی توسط هر سازنده مرورگر توسعه یافتند و ناسازگار باقی ماندند. این نسخه های DOM به «DOM متوسط» معروف شدند. پس از استانداردسازی ECMAScript، گروه کاری W3C DOM شروع به تهیه پیش نویس مشخصات استاندارد DOM کرد. مشخصات تکمیل شده، معروف به DOM Level 1، در اواخر سال 1998 به توصیه W3C تبدیل شد. تا سال 2005، بخش های بزرگی از W3C DOM توسط مرورگرهای رایج دارای ECMAScript، از جمله Microsoft Internet Explorer نسخه 6 (از سال 2001) به خوبی پشتیبانی می شد. مرورگرهای مبتنی بر Opera، Safari و Gecko مانند Mozilla، Firefox، SeaMonkey و Camino.
HTML برای ساختار صفحات وب و جاوا اسکریپت برای افزودن رفتار به صفحات وب استفاده می شود. هنگامی که یک فایل HTML در مرورگر بارگذاری می شود، جاوا اسکریپت نمی تواند به طور مستقیم سند HTML را دستکاری کند. بنابراین، یک Document مربوطه به نام DOM ایجاد می شود.DOM اساسا نمایش همان سند HTML اما در قالبی متفاوت با استفاده از اشیا است. جاوا اسکریپت DOM را به راحتی تفسیر می کند، یعنی جاوا اسکریپت نمی تواند تگ ها را در سند HTML درک کند اما می تواند شی h1 را در DOM درک کند. اکنون جاوا اسکریپت می تواند با استفاده از توابع مختلف به هر یک از اشیا (h1، p و غیره) دسترسی داشته باشد.
اسناد با استفاده از اشیا مدلسازی میشوند و این مدل نه تنها شامل ساختار یک سند، بلکه رفتار یک سند و اشیایی است که از عناصر تگ مانند با ویژگیهایی در HTML تشکیل شده است.این مدل در یک ساختار درختی از اشیا ساخته شده است و موارد زیر را تعریف می کند:
شی document نماینده صفحه وب شما و صاحب تمام اشیا دیگر در سند HTML است. بنابراین اگر بخواهید به عنصری در HTML دسترسی پیدا کنید باید با شی document شروع کنید. برای شما چند مثال آورده ایم:
متد | توضیحات |
document.getElementById(id) | پیدا کردن عنصر با استفاده از id |
document.getElementsByTagName(name) | پیدا کردن عنصر با استفاده از نام تگ |
document.getElementsByClassName(name) | پیدا کردن عنصر با استفاده از نام کلاس |
خصوصیت (property) | توضیحات |
element.innerHTML = new html content | تغییر دادن inner HTML (محتوای) یک عنصر |
element.attribute = new value | تغییر دادن مقدارِ attribute یک عنصر |
element.style.property = new style | تغییر استایل (CSS) یک عنصر |
متد | توضیحات |
element.setAttribute(attribute, value) | تغییر دادن مقدارِ attribute یک عنصر |
متد | توضیحات |
document.createElement(element) | ساختن یک عنصر HTML |
document.removeChild(element) | حذف کردن یک عنصر HTML |
document.appendChild(element) | اضافه کردن یک عنصر HTML |
document.replaceChild(new, old) | جایگزین کردن یک عنصر HTML |
document.write(text) | نوشتن در خروجی یک عنصر HT |
متد | توضیحات |
document.getElementById(id).onclick = function(){code} | اضافه کردن event handler به رویدادِ onclick |
در این جا اشیا و انواع مختلف را به زبان ساده توصیف می کنیم.
توجه: از آن جا که بیش تر کدهایی که از DOM استفاده میکنند برای دستکاری اسناد HTML هستند، معمولا به گره (node) های DOM به عنوان المنت اشاره میشود، در حالی که گره یک المنت نیست.جدول زیر به طور خلاصه این نوع داده ها را توضیح می دهد.
جدول زیر به طور خلاصه انواع داده ها را توضیح می دهد.
هنگامی که یک المنت یک شی از نوع document را برمی گرداند (به عنوان مثال، ویژگی ownerDocument از یک المنت، document را که به آن تعلق دارد برمی گرداند)، این شی، خود شی document ریشه یا root است. | Document |
هر شی که در یک document قرار دارد یک نوع node (گره) است. در یک سند HTML، یک شی می تواند یک گره element، بلکه یک گره text یا گره attribute باشد. | Node |
نوع element بر اساس node است. به یک المنت یا یک node از نوع المنت بازگردانده شده توسط یکی از DOM API ها اشاره دارد. به عنوان مثال به جای این که بگوییم متد document.createElement() یک مرجع شی را به یک node برمی گرداند، فقط می گوییم که این متد المنتی را که به تازگی در DOM ایجاد شده است برمی گرداند. اشیا عنصر رابط DOM Element و هم چنین رابط اصلی Node را پیاده سازی می کنند. در یک سند HTML، عناصر توسط رابط HTMLElement و هم چنین سایر رابطهایی که قابلیتهای انواع خاصی از عناصر را توصیف میکنند (به عنوان مثال، HTMLTableElement برای table) معرفی میشوند. | Element |
یک nodeList آرایه ای از عناصر است، مانند نوعی که توسط متد document.querySelectorAll برگردانده می شود. آیتمهای موجود در nodeList به یکی از دو روش زیر از طریق اندیس شان قابل دسترسی هستند:
list.item(1) list[1] دو خط بالا معادل هستند. در خط اول،item() تنها متد موجود برای شی nodeList است. دومی از یک آرایه معمولی برای به دست آوردن آیتم دوم در آرایه استفاده می کند. |
NodeList |
هنگامی که یکattribute توسط یک عضو برگردانده می شود (به عنوان مثال، توسط متد ()createAttribute). یک مرجع شی است که یک رابط خاص را برای attribute ها نشان می دهد. attribute ها مانند المنت ها گرههایی در DOM هستند، اگرچه ممکن است به ندرت از آنها استفاده کنیم. | Attr |
یک namedNodeMap مانند یک آرایه است، اما آیتم ها با نام یا اندیس قابل دسترسی هستند. namedNodeMap یک متد item() برای این منظور دارد و هم چنین میتوانید آیتمهایی را از یک namedNodeMap اضافه و حذف کنید. | NamedNodeMap |
در این جا نکته هایی وجود دارد که باید در نظر داشته باشید. به عنوان مثال، به هر گره Attr به عنوان یک attribute اشاره می شود و به آرایه ای از گره های DOM یک nodeList می گویند.
برخی از این موارد را برای شما در جدول های زیر آورده ایم:
خصوصیت |
توضیحات |
document.anchors |
تمام <a> هایی را برمی گرداند که دارای attribute ای به نام name باشند |
document.baseURI |
base URI مربوط به سند را به ما برمی گرداند |
document.body | عنصر <body> را به ما برمی گرداند |
document.cookie | تمام cookie های سند را به ما برمی گرداند |
document.doctype | doctype (نوع سند) را به ما برمی گرداند |
document.documentElement | عنصر <html> را برمی گرداند |
document.documentMode | mode ای که توسط مرورگر استفاده می شود را برمی گرداند |
document.documentURI | URI سند فعلی را برمی گرداند |
document.domain | نام دامنه سرور سند را برمی گرداند |
document.embeds | تمام عناصر <embed> را برمی گرداند |
document.forms | تمام عناصر <form> را برمی گرداند |
document.head | عنصر <head> را برمی گرداند |
document.images | تمام عناصر <img> را برمی گرداند |
document.implementation | تمام پیاده ساز های DOM را برمی گرداند |
document.inputEncoding | encoding (همان character set) سند را برمی گرداند. |
document.lastModified | تاریخ و زمانی که در آن، سند برای آخرین بار بروزرسانی شده است را برمی گرداند |
document.links | تمام <area> و <a> هایی را برمی گرداند که href داشته باشند |
document.readyState | موقعیت (loading) سند را برمی گرداند |
document.referrer | URI مربوط به سندِ متصل (referrer) را برمی گرداند |
در این قسمت با DOM آشنا شدیم و برخی از متدها و خصوصیات آن را به صورت لیست وار ذکر کردیم. در قسمت های بعد به مثال های عملی رسیده و این متدها و خصوصیات را به طور عملی مورد استفاده قرار خواهیم داد. امیدوارم این قسمت برای شما مفید بوده باشد.
سطح 0: مجموعه ای از رابط های سطح پایین را ارائه می دهد.
سطح 1: سطح 1 DOM را می توان در دو بخش CORE و HTML توصیف کرد. COREرابط های سطح پایینی را ارائه می دهد که می تواند برای نمایش هر سند ساختاری استفاده شود. HTML رابط های سطح بالایی را ارائه می دهد که می توانند برای نشان دادن اسناد HTML استفاده شوند.
سطح 2: شامل شش ویژگی CORE2، VIEWS، EVENTS، STYLE، TRAVERSAL و RANGE است.
CORE2: عملکرد CORE مشخص شده توسط DOM سطح 1 را گسترش می دهد.
VIEWS: به برنامه ها اجازه می دهد تا به صورت پویا به محتوای سند دسترسی پیدا کرده و آن را دستکاری کنند.
EVENTS: رویدادها اسکریپت هایی هستند که در هنگام واکنش کاربر به صفحه وب توسط مرورگر اجرا می شوند.
STYLE: به برنامه ها اجازه می دهد تا به صورت پویا به محتوای فایل های style دسترسی داشته باشند و آن ها را دستکاری کنند.
TRAVERSAL: این به برنامه ها اجازه می دهد تا به صورت پویا در document گردش داشته باشند.
RANGE: این به برنامه ها اجازه می دهد تا به صورت پویا محدوده ای از محتوا را در document شناسایی کنند.
سطح 3: شامل پنج ویژگی مختلف است: CORE3، LOAD و SAVE، VALIDATION، EVENTS و XPATH.
CORE3: عملکرد CORE مشخص شده توسط DOM سطح 2 را گسترش می دهد.
LOAD and SAVE: این به برنامه اجازه می دهد تا محتوای سند XML را به صورت پویا در سند DOM بارگذاری کند و با سریال سازی، سند DOM را در یک سند XML ذخیره کند.
VALIDATION: این به برنامه اجازه میدهد تا محتوا و ساختار document را بهصورت پویا بهروزرسانی کند و در عین حال از معتبر ماندن document اطمینان حاصل کند.
EVENTS: قابلیت رویدادهای مشخص شده توسط DOM Level 2 را گسترش می دهد.
XPATH: یک زبان مسیر است که می توان از آن برای دسترسی به درخت DOM استفاده کرد.
این بخش تعدادی از متداول ترین رابط های مورد استفاده در DOM را فهرست می کند.اشیا document و window اشیایی هستند که معمولا از رابط آن ها در برنامه نویسی DOM استفاده می شود. به عبارت ساده، شی window چیزی شبیه مرورگر را نشان می دهد و شی document ریشه خود document است. عنصر از رابط Node عمومی به ارث میرسد و این دو رابط با هم بسیاری از متدها و ویژگیهایی را که در المنت های جداگانه استفاده میکنید ارائه میکنند.
در زیر لیست مختصری از APIهای رایج در برنامه نویسی صفحات وب و XML با استفاده از DOM آمده است.
جاوا اسکریپت از DOM برای دسترسی به document و عناصر آن استفاده می کند. DOM یک زبان برنامه نویسی نیست، اما بدون آن، زبان جاوا اسکریپت هیچ مدل یا مفهومی از صفحات وب، اسناد HTML، اسناد SVG و اجزای سازنده آن ها نخواهد داشت. document به عنوان یک کل، head، table ها، هدرهای جدول، متن درون سلولهای جدول، و تمام عناصر دیگر در یک document، بخشهایی از DOM هستند. همه آن ها با استفاده از DOM و یک زبان برنامه نویسی مانند جاوا اسکریپت قابل دسترسی و دستکاری هستند.
DOM بخشی از زبان جاوا اسکریپت نیست، بلکه یک وب API است که برای ساخت وب سایت ها استفاده می شود. جاوا اسکریپت را می توان در زمینه های دیگر نیز استفاده کرد. به عنوان مثال، Node.js برنامه های جاوا اسکریپت را بر روی کامپیوتر اجرا می کند، اما مجموعه متفاوتی از API ها را ارائه می دهد، و DOM API بخشی اصلی از runtime نود نیست.
DOM به گونه ای طراحی شده بود که مستقل از هر زبان برنامه نویسی خاصی باشد و نمایش ساختاری سند را از یک API یکتا و سازگار در دسترس قرار دهد. حتی اگر اکثر توسعه دهندگان وب فقط از DOM استفاده کنند، پیاده سازی DOM را می توان برای هر زبانی ساخت، همان طور که این مثال پایتون نشان می دهد:
# Python DOM example import xml.dom.minidom as m doc = m.parse(r"C:\Projects\Py\chap1.xml") doc.nodeName # DOM property of document object p_list = doc.getElementsByTagName("para")
برای اطلاعات بیش تر در مورد این که چه فناوری هایی در نوشتن جاوا اسکریپت دخیل هستند، به نشانی مراجعه کنید.
برای شروع استفاده از DOM لازم نیست کار خاصی انجام دهید. می توانید مستقیما از API موجود در جاوا اسکریپت از درون چیزی که اسکریپت نامیده می شود، استفاده کنید. هنگامی که یک اسکریپت ایجاد می کنید، چه به صورت درون خطی (inline) یا در این که در صفحه وب گنجانده شده باشد، می توانید اشیا document یا window را برای دستکاری کنید. برنامه نویسی DOM ممکن است چیزی به سادگی مثال زیر باشد که با استفاده از تابع console.log پیامی را در کنسول نمایش می دهد:
<body onload="console.log('Welcome to my home page!');">
DOM Level 1 یک مدل کامل برای کل یک سند HTML یا XML، از جمله ابزارهایی برای تغییر هر بخشی از سند ارائه کرد.
DOM Level 2 در اواخر سال 2000 منتشر شد. تابع getElementById و هم چنین یک مدل رویداد و پشتیبانی از فضاهای نام XML و CSS را معرفی کرد.
DOM Level 3 که در آوریل 2004 منتشر شد، پشتیبانی از XPath و مدیریت رویدادهای صفحه کلید و هم چنین رابطی برای سریال سازی اسناد به عنوان XML اضافه کرد.
DOM Level 4 در سال 2015 منتشر شد. یک نسخه از استاندارد WHATWG است.
اکنون که میدانیم DOM چیست، میتوانیم المنت های HTML را دریافت و دستکاری کنیم. راه های مختلفی برای انجام این کار با استفاده از Javascript DOM وجود دارد که در این جا مهم ترین آن ها آورده شده اند:
متد getElementById برای بدست آوردن یک عنصر با Id آن استفاده می شود. بیایید به یک مثال نگاه کنیم:
var title = document.getElementById(‘header-title’);
در این جا المنتی را که Id آن header-title است دریافت می کنیم و آن را در یک متغیر ذخیره می کنیم.
هم چنین میتوانیم بیش از یک شی را با استفاده از متد ()getElementsByClassName دریافت کنیم که آرایهای از المنت ها را برمیگرداند.
var items = document.getElementsByClassName(‘list-items’);
در این جا همه آیتمها را با کلاس list-items دریافت کرده و در یک متغیر ذخیره میکنیم.
با استفاده از متد ()getElementsByTagName میتوانیم المنت ها را با نام تگ دریافت کنیم.
var listItems = document.getElementsByTagName(‘li’);
در این جا ما تمام تگ ها li را دریافت کرده و آن ها را در یک متغیر ذخیره می کنیم.
متد querySelector اولین المنتی را برمی گرداند که با selector (گزینشگر) CSS مشخص شده مطابقت دارد. این به این معنی است که می توانید المنت ها را بر اساس Id، کلاس، تگ و سایر گزینشگرهای CSS دریافت کنید. در این جا فقط تعدادی از مهم ترین آن ها را آورده ام:
var header = document.querySelector(‘#header’)
var items = document.querySelector(‘.list-items’)
var headings = document.querySelector(‘h1’);
هم چنین میتوانیم با استفاده از گزینشگرهای CSS، عناصر خاصتری را دریافت کنیم.
document.querySelector(“h1.heading”);
در مثال بالا ما یک تگ و یک کلاس را همزمان جستجو می کنیم و اولین عنصری را که با گزینشگر css مطابقت داشته باشد را برمی گردانیم.
متد querySelectorAll کاملا مشابه querySelector است با این تفاوت که تمام عناصر متناسب با گزینشگر (selector) CSS را برمی گرداند.
var heading = document.querySelectorAll(‘h1.heading’);
در این مثال، همه تگ های h1 را که دارای یک کلاس heading هستند، دریافت کرده و در یک آرایه ذخیره می کنیم.
HTML DOM به ما این امکان را می دهد که محتوا و استایل یک عنصر HTML را با تغییر ویژگی های آن تغییر دهیم.
از ویژگی innerHTML می توان برای تغییر محتوای یک عنصر HTML استفاده کرد.
document.getElementById(“#header”).innerHTML = “Hello World!”;
در این مثال، یک المنت را با id یا شناسه header دریافت می کنیم و محتوای آن را Hello World! قرار می دهیم. InnerHTML هم چنین می تواند برای قرار دادن تگ ها در یک تگ دیگر استفاده شود.
document.getElementsByTagName("div").innerHTML = "<h1>Hello World!</h1>"
در این جا ما یک تگ h1 را در تمام div های موجود قرار می دهیم.
هم چنین می توانید مقدار یک attribute را با استفاده از DOM تغییر دهید.
document.getElementsByTag(“img”).src = “test.jpg”;
در این مثال ما src تمام تگ های img را به test.jpg تغییر می دهیم.
برای تغییر استایل یک عنصر HTML باید ویژگی style عناصر خود را تغییر دهیم. در زیر یک مثال آورده شده است:
document.getElementById(id).style.property = new style
حالا بیایید به مثالی نگاه کنیم که در آن یک المنت دریافت می کنیم و border پایین را به یک خط سیاه ثابت تغییر می دهیم:
document.getElementsByTag(“h1”).style.borderBottom = “solid 3px #000”;
ویژگی های CSS باید به شکل کوهان شتری یا camelcase نوشته شوند. در این مثال از borderBottom به جای border-bottom استفاده کردیم.
اکنون نگاهی به نحوه اضافه کردن عناصر جدید و حذف عناصر موجود خواهیم انداخت.
var div = document.createElement(‘div’);
در این جا ما فقط با استفاده از متد createElemen یک عنصر div ایجاد می کنیم که نام تگ را به عنوان پارامتر می گیرد و آن را در یک متغیر ذخیره می کند.پس از آن فقط باید محتوا به آن بدهیم و سپس آن را در سند DOM خود وارد کنیم.
var newContent = document.createTextNode("Hello World!"); div.appendChild(newContent); document.body.insertBefore(div, currentDiv);
در این جا ما محتوا را با استفاده از متد ()createTextNode ایجاد می کنیم که یک String را به عنوان پارامتر می گیرد. سپس عنصر div جدید خود را پیش از div موجود در document وارد می کنیم.
var elem = document.querySelector('#header'); elem.parentNode.removeChild(elem);
در این جا یک عنصر دریافت می کنیم و با استفاده از متد removeChild آن را حذف می کنیم.
حالا بیایید نگاهی به نحوه جایگزینی المنت ها بیندازیم.
var div = document.querySelector('#div'); var newDiv = document.createElement(‘div’); newDiv.innerHTML = "Hello World2" div.parentNode.replaceChild(newDiv, div);
در این جا یک عنصر را با استفاده از متد ()placeChild جایگزین می کنیم. آرگومان اول عنصر جدید و آرگومان دوم عنصری است که می خواهیم جایگزین کنیم.
هم چنین میتوانیم عبارات HTML و جاوا اسکریپت را مستقیما در جریان خروجی HTML با استفاده از متد write بنویسیم.
document.write(“<h1>Hello World!</h1><p>This is a paragraph!</p>”);
متد ()write هم چنین میتواند چندین آرگومان بگیرد که به ترتیب وقوع به document اضافه میشوند.
HTML DOM هم چنین به جاوا اسکریپت اجازه می دهد تا به رویدادهای HTML واکنش نشان دهد. در این جا فقط برخی از مهم ترین آن ها را فهرست کرده ام:
شما می توانید رویدادها را مستقیما در کد HTML خود با استفاده از ویژگی های تگ های خود تعریف کنید. در اینجا یک مثال از رویداد onclick آمده است:
<h1 onclick=”this.innerHTML = ‘Hello!’”>Click me!</h1>
در این مثال وقتی روی دکمه کلیک می کنید، متن h1 به "!Hello" تغییر می کند. همان طور که در مثال بعدی مشاهده می کنید، می توانید هنگام راه اندازی یک رویداد، توابع را فراخوانی کنید.
<h1 onclick=”changeText(this)”>Click me!</h1>
در این جا متد changeText را هنگامی که دکمه کلیک میشود فراخوانی میکنیم و المنت را به عنوان یک ویژگی به آن می فرستیم.هم چنین میتوانیم همان رویدادها را در کد جاوا اسکریپت خود اختصاص دهیم.
document.getElementById(“btn”).onclick = changeText();
حال بیایید ببینیم چگونه میتوانید شنوندگان رویداد را به المنت هاس HTML خود اختصاص دهید.
document.getElementById(“btn”).addEventListener('click', runEvent);
در این جا ما فقط یک رویداد کلیک را اختصاص دادیم که وقتی عنصر btn شما کلیک میشود، متد runEvent را فراخوانی میکند.هم چنین می توانید چندین رویداد را به یک عنصر اختصاص دهید:
document.getElementById(“btn”).addEventListener('mouseover', runEvent);
گره ها در سند DOM یک رابطه سلسله مراتبی با یکدیگر دارند. این بدان معنی است که گره ها مانند یک درخت ساخته شده اند. ما از اصطلاحات پدر، خواهر و برادر و فرزند برای توصیف رابطه بین گره ها استفاده می کنیم.گره بالایی root نامیده می شود و تنها گره ای است که پدر ندارد. ریشه در یک سند معمولی HTML تگ html است زیرا پدر ندارد و تگ بالای document است.
می توانیم با استفاده از این ویژگی ها بین گره ها حرکت کنیم:
در این جا مثالی آورده شده است که نشان می دهد چگونه می توانید پدر یک h1 را به دست آورید.
var parent = document.getElementById(“heading”).parentNode
برای یادگیری بیش تر DOM بهتر است آن را در قالب یک پروژه پیاده کنیم. این پروژه ما را با ویژگی ها و توانمندی های DOM در جاوا اسکریپت بهتر آشنا می کند. این پروژه از سه input تشکیل شده است. input اول برای جستجو یا فیلتر کردن در بین لیست است و input دوم برای افزودن آیتم جدید به لیست است. می توان آیتم ها را با دکمه رو به رو آن ها حذف کرد. inout سوم برای Submit کردن است.تصویر پروژه در زیر آمده است:
در آغاز یک پوشه به نام learn-dom بسازید.نام پوشه اختیاری است.سپس دو فایل index.html و script.js را در آن ایجاد کنید.
کد زیر را در index.html قرار دهید.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <title>Learn DOM </title> </head> <body> <header id="main-header" class="bg-success text-white p-4 mb-3"> <div class="container"> <div class="row"> <div class="col-md-6"> <h1 id="header-title">Item Lister</h1> </div> <div class="col-md-6 align-self-center"> <input type="text" class="form-control" id="filter" placeholder="Search Items..."> </div> </div> </div> </header> <div class="container"> <div id="main" class="card card-body"> <h2 class="title">Add Items</h2> <form id="addForm" class="form-inline mb-3"> <input type="text" class="form-control mr-2" id="item"> <input type="submit" class="btn btn-dark" value="Submit"> </form> <h2 class="title">Items</h2> <ul id="items" class="list-group"> <li class="list-group-item">Item 1 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 2 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 3 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 4 <button class="btn btn-danger btn-sm float-right delete">X</button></li> </ul> </div> </div> <script src="script.js"></script> </body> </html>
در این قسمت تنها بخش های مهم کد بالا را بررسی می کنیم.کد بالا از یک input برای جستجو یا فیلتر کردن آیتم های لیست استفاده می کند.این input در یک div با کلاس col-md-6 قرار دارد.این کلاس متعلق به bootstrap است. در این جا تنها به آموزش DOM خواهیم پرداخت و کاری به استایل برنامه نداریم.پس به آن اهمیتی نمی دهیم.
<div class="col-md-6 align-self-center"> <input type="text" class="form-control" id="filter" placeholder="Search Items..."> </div>
input بالا دارای id با مقدار filter است.از این id برای دستیابی به این input استفاده خواهیم کرد. در ادامه یک فرم برای افزودن آیتم ها داریم.id این فرم addForm است. از نام آن می توان حدس زد که چه کاری می کند.این فرم خود از دو input تشکیل شده است. input اول برای دریافت ورودی و افزودن آن به لیست آیتم ها است.input دوم از نوع submit برای تایید افزودن است.
<form id="addForm" class="form-inline mb-3"> <input type="text" class="form-control mr-2" id="item"> <input type="submit" class="btn btn-dark" value="Submit"> </form>
input اول دارای id با مقدار item است. از این id برای دستیابی به این input استفاده خواهیم کرد.
سپس یک تگ ul با تعدادی تگ li داریم.id تگ ul در این جا items است.از این id برای دسترسی به ul استفاده خواهیم کرد.هر کدام از این li ها نشان دهنده یک item در لیست هستند.کلاس li ها list-group-item است.این کلاس متعلق به bootstrap است.هر li دارای یک دکمه با کلاس btn btn-danger btn-sm است.
<ul id="items" class="list-group"> <li class="list-group-item">Item 1 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 2 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 3 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 4 <button class="btn btn-danger btn-sm float-right delete">X</button></li> </ul>
تا این جا فایل index.html را بررسی کردیم.حالا نوبت فایل script.js است.
همان طور که در پیش گفته شد می توان با javascript یا به طور دقیق تر به عناصر یا المنت های HTML دست یافت. فایل کامل script.js در زیر آمده است:
var form = document.getElementById('addForm'); var itemList = document.getElementById('items'); var filter = document.getElementById('filter'); // Form submit event form.addEventListener('submit', addItem); // Delete event itemList.addEventListener('click', removeItem); // Filter event filter.addEventListener('keyup', filterItems); // Add item function addItem(e){ e.preventDefault(); // Get input value var newItem = document.getElementById('item').value; // Create new li element var li = document.createElement('li'); // Add class li.className = 'list-group-item'; // Add text node with input value li.appendChild(document.createTextNode(newItem)); // Create del button element var deleteBtn = document.createElement('button'); // Add classes to del button deleteBtn.className = 'btn btn-danger btn-sm float-right delete'; // Append text node deleteBtn.appendChild(document.createTextNode('X')); // Append button to li li.appendChild(deleteBtn); // Append li to list itemList.appendChild(li); } // Remove item function removeItem(e){ if(e.target.classList.contains('delete')){ if(confirm('Are You Sure?')){ var li = e.target.parentElement; itemList.removeChild(li); } } } // Filter Items function filterItems(e){ // convert text to lowercase var text = e.target.value.toLowerCase(); // Get lis var items = itemList.getElementsByTagName('li'); // Convert to an array Array.from(items).forEach(function(item){ var itemName = item.firstChild.textContent; if(itemName.toLowerCase().indexOf(text) != -1){ item.style.display = 'block'; } else { item.style.display = 'none'; } }); }
سه خط اول کد برای دسترسی به المنت های HTML هستند.در این جا از بین همه المنت های HTML به سه تا از آن ها نیاز داریم.به form به ul و به input که برای فیلتر کردن است نیاز داریم. هر کدام از آن ها را در متغیری ذخیره می کنیم.به هر سه المنت بر اساس id شان دسترسی پیدا می کنیم. این کار را با getElementById انجام می دهیم. پارامتری که این متد می گیرد id المنت مورد نظر است.
گام بعدی افزودن شونده رویداد یا event listener به آن ها است.به فرم رویداد submit، به ul که در متغیر itemsList ذخیره شده است رویداد click و به input مخصوص فیلتر کردن که در متغیر filter ذخیره شده است رویداد keyup را اضافه می کنیم. این کار را با متد addEventListener انجام می دهیم.
addEventListener سه پارامتر می گیرد. پارامتر اول برای تعیین نوع رویداد پارامتر سوم یک تابع برای مدیریت رویداد و پارامتر سوم یک مقدار بولی است که مشخص می کند از event bubbling استفاده شود یا event capturing. در این جا از پارامتر سوم استفاده نمی کنیم.
برای اضافه کردن آیتم تابع addItem، برای حذف آیتم تابع removeItem و برای فیلتر کردن تابع filterItems را تعریف می کنیم. هر سه این تابع ها در addEventListener استفاده شده اند.
// Form submit event form.addEventListener('submit', addItem); // Delete event itemList.addEventListener('click', removeItem); // Filter event filter.addEventListener('keyup', filterItems);
// Add item function addItem(e){ e.preventDefault(); // Get input value var newItem = document.getElementById('item').value; // Create new li element var li = document.createElement('li'); // Add class li.className = 'list-group-item'; // Add text node with input value li.appendChild(document.createTextNode(newItem)); // Create del button element var deleteBtn = document.createElement('button'); // Add classes to del button deleteBtn.className = 'btn btn-danger btn-sm float-right delete'; // Append text node deleteBtn.appendChild(document.createTextNode('X')); // Append button to li li.appendChild(deleteBtn); // Append li to list itemList.appendChild(li); }
این تابع برای اضافه کردن آیتم جدید به لیست است. این تابع پارامتر e را که نشان دهنده رویداد است می گیرد. رویداد پیش فرض فرم submit شدن با فشرده شدن Enter است با کد زیر این رویداد را بی اثر می کنیم.
e.preventDefault();
سپس مقداری که در input با آی دی item نوشته می شود را می گیریم.یک تگ li جدید را با createElement درست می کنیم.
// Get input value var newItem = document.getElementById('item').value; // Create new li element var li = document.createElement('li');
سپس به تگ li کلاس list-group-item را اضافه می کنیم. برای مقداری که در input نوشته شده است، با استفاده از متد createTextNode یک گره متن ایجاد می کنیم و آن را در li قرار می دهیم. این کار را با متد appendChild انجام می دهیم.
// Add class li.className = 'list-group-item'; // Add text node with input value li.appendChild(document.createTextNode(newItem));
همه کارهای بالا را برای ایجاد یک دکمه حذف انجام می دهیم.
// Create del button element var deleteBtn = document.createElement('button'); // Add classes to del button deleteBtn.className = 'btn btn-danger btn-sm float-right delete'; // Append text node deleteBtn.appendChild(document.createTextNode('X')); // Append button to li li.appendChild(deleteBtn);
در آخر li را در ul که در itemsList ذخیره شده است قرار می دهیم.
// Append li to list itemList.appendChild(li);
// Remove item function removeItem(e){ if(e.target.classList.contains('delete')){ if(confirm('Are You Sure?')){ var li = e.target.parentElement; itemList.removeChild(li); } } }
این تابع پارامتر e را که نشان دهنده رویداد است می گیرد. تابع بالا منطق ساده ای دارد. این تابع در همه المنت های HTML می گردد و همه آن هایی را که دارای کلاس delete هستند پیدا می کند (این کلاس در قسمت قبل به دکمه حذف اضافه شده است). اگر المنتی کلاس delete را داشته باشد یک confirm به کاربر نشان داده می شود. در این confirm از کاربر خواسته می شود تا جواب خود را بفرستد. اگر کاربر دکمه ok فشرده شود li حذف می شود.
// Filter Items function filterItems(e){ // convert text to lowercase var text = e.target.value.toLowerCase(); // Get lis var items = itemList.getElementsByTagName('li'); // Convert to an array Array.from(items).forEach(function(item){ var itemName = item.firstChild.textContent; if(itemName.toLowerCase().indexOf(text) != -1){ item.style.display = 'block'; } else { item.style.display = 'none'; } }); }
این تابع پارامتر e را که نشان دهنده رویداد است می گیرد.این تابع برای فیلتر کردن آیتم های لیست است.در input کلمه ای را می نویسیم و این تابع در بین آیتم های لیست می گردد و آن هایی را که با کلمه وارد شده مطابقت دارند برمی گرداند. متنی که در input وارد می شود را با استفاده از متد toLowerCase به حروف کوچک تبدیل می کنیم تا نتیجه جستجو حساس به حالت نباشد یعنی به حروف کوچک و بزرک حساس نباشد.
کلمه ای که در input وارد شده است را باید با تک تک li ها مقایسه می کنیم. ابتدا همه li ها را می گیریم. سپس با استفاده از یک حلقه کلمه وارد شده در input را با li ها مقایسه می کنیم.اگر کلمه با یکی از li ها مطابقت داشته باشد آن li ثابت سر جای خود می ماند و بقیه li ها ناپدید می شوند. اگر با همه مطابقت داشته باشد هیچ کدام از آن ها ناپدید نمی شوند. ممکن است کلمه با چند li مطابقت داشته باشد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.