Dom چیست؟
کلمه DOM مخفف Document Object Model به معنای مدل شی گرای سند یکی دیگر از مفاهیم اصلی در جاوا اسکریپت است. با استفاده از DOM میتوان امکان دسترسی به عناصر موجود در صفحه فراهم شود. همچنین دستکاری عنصرها و اضافه، حذف کردن و جابه جایی عناصر را در صفحه امکان پذیر میکند.
برای مثال فرض کنید یک صفحه HTML طراحی کرده و حالا میخواهید عناصر موجود در صفحه را دستکاری کنید. مثلا دکمه ای تعبیه کنید که با کلیک کاربر بر روی آن بخشی از صفحه تغییر کند و یا اصلا نمایش داده نشود. در این بین تنها کاری که باید انجام دهید استفاده از DOM است که این امکان را به شما میدهد تا ویرایشهای لازم را انجام دهید.
این مدل عناصر موجود در یک صفحه HTML را به صورت درختی و دارای چندین گره رسم کرده است. همانطور که میدانید در HTML ریشه اصلی درخت html میباشد اما در DOM همیشه یک ریشه به نام Document وجود دارد که در بالاترین سطح درخت قرار گرفته است و دیگر زیرشاخهها (یا گره) را شامل میشود. به تصویر زیر توجه کنید:
درخت بالا را میتوان به صورت زیر نوشت :
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>DOM tree structure</title> </head> <body> <h1>Learn about the DOM</h1> <h2>Do you know what DOM is?</h2> </body> </html>
هرکدام از تگهای html ، head ، body میتوانند زیر شاخه داشته باشند. اما تگهای meta ، title ، h1 ، h2 نمیتوانند زیر شاخه داشته باشند.
در این بخش پاورپوینت جاوا اسکریپت ES6 قرار داده شده است. جاوا اسکریپت ES6 یا اکما اسکریپت (ECMAScript) یک استاندارد جدید است که برای هرچه بهتر شدن جاوا اسکریپت ارائه شده است. با کلیک روی لینک زیر میتوانید این محصول را دانلود کنید.
انواع گره ها در DOM
گفتیم که هر تگ در html یک گره محسوب میشود. برخی از این گره ها میتوانند زیر شاخه داشته باشند و برخی دیگر نمیتوانند. گره ها انواع مختلفی دارند. در مجموع ۱۱ نوع گره وجود دارد اما ۴ نوع از این گره ها بیشتر مورد استفاده قرار میگیرد و آشنایی با این ۴ مورد کافی است. این گره ها عبارتند از :
- Document : عنصر ریشه درخت است. بالاترین گره ای است که بقیه گره ها زیر شاخه آن هستند. این نوع گره، گره سند (Document Node) نام دارد.
- Element : تگ های html هستند. این نوع گره ها داری یک تگ شروع و یک تگ پایان است. (مانند ) این نوع گره ها تنها نوع از زیر شاخه هستند که میتوانند شامل زیر شاخه های دیگر شوند. به این نوع از گره ها، گره عنصری (Element Node) گفته میشود.
- attr : صفتهای داخل تگ های html هستند. این گره زیرشاخه ای از تگ های html محسوب میشود و خود نمیتواند دارای زیر شاخه باشد. به این گره ها، گره صفتی (Attribute Node) گفته میشود. معمولا در نمودار درختی DOM این گره ها را به صورت دایرهای رسم میکنند که نشان دهنده اتصال به گرههای عنصری است. برای مثال تگ a (لینک) دارای دو صفت است که میتوان به صورت زیر نشان داد:
این گره را میتوان به صورت زیر نوشت:
<a rel="nofollow" href="https://programstore.ir">Link Text - Click</a>
- text : این نوع گره ها از نوع متنی هستند که در داخل تگ های html قرار میگیرند. این نوع نمیتوانند زیر شاخه داشته باشند. به این نوع گره ها، گره متنی (Text Node) گفته میشود. اگر بخواهیم گره های متنی را به مثال اول اضافه کنیم نمودار درختی ما بدین صورت خواهد بود:
استفاده از DOM
همانطور که در پست قبلی گفتیم، BOM و DOM از اجزای اصلی تشکیل دهنده جاوا اسکریپت میباشند.
اگر بخواهیم به گره ها دسترسی داشته باشیم چکار باید انجام دهیم؟ برای این کار میتوان از خاصیت documentElement استفاده کرد که در واقع یکی از خاصیت های شیء Document است. به طور کلی این دستور را میتوان به صورت زیر نوشت :
document.documentElement
گره ها در جاوا اسکریپت نوعی اشیاء درنظر گرفته میشوند. بنابراین این اشیاء ها میتوانند دارای متدهایی نیز باشند. گره Element دارای چند متد میباشد که در جدول زیر به آن ها اشاره میکنیم:
به عنوان مثال برای به دست آوردن نام گره یک سند از متد nodeName استفاده میشود. برای درک بهتر به مثال زیر توجه کنید:
<button onclick="myFunction()">Try it</button> <script> function myFunction() { var x = document.documentElement.nodeName; alert(x); } </script> //result HTML
یا برای دانستن اولین گره از یک لیست به صورت زیر عمل میکنیم:
<p>Example list:</p> <ul id="myList"><li>Coffee</li><li>Tea</li></ul> <p>Click the button to know the first node.</p> <button onclick="myFunction()">Try it</button> <script> function myFunction() { var list = document.getElementById("myList").firstChild.innerHTML; alert(list); } </script>
در مثال بالا ابتدا یک لیست با آیدی myList تشکیل دادیم و سپس در ادامه، داخل تابع با متد firstChild گره ای که اولین بار ایجاد شده است اشاره کردیم و در یک متغیر ذخیره کردیم. درنهایت محتویات داخل متغیر را چاپ کردیم.
برای به دست آوردن تعداد گره ها در یک سند میتوانیم از دستور زیر استفاده کنیم:
<p>Hello World!</p> <p>Isn’t this exciting?</p> <p>You’re learning to use the DOM!</p> <button onclick="myFunction()">Try it</button> <script> function myFunction() { var oHtml = document.documentElement; alert(oHtml.childNodes.length); } </script> //result 3
از آنجایی که در تکه کد بالا سه پاراگراف وجود دارد بنابراین تعداد گره ها برابر با ۳ است.
برای دسترسی به عنصر body از دستور زیر استفاده میشود:
document.body
دسترسی به گره های خاص
در ادامه پست آموزشی DOM در جاوا اسکریپت میخواهیم نحوه دسترسی به یک گره خاص که حتی ممکن است در عمق یک درخت قرار گرفته باشد یاد بگیریم. تا به اینجای کار با دسترسی به گره های مادر و زیرشاخه های آنها آشنا شدیم، اما اگر بخوایم به یک گره خاصی دسترسی داشته باشیم چه باید کرد؟
برای این کار چندین متد از DOM وجود دارد که در ادامه به توضیح هرکدام از آنها میپردازیم:
()getElementsByTagName
در این متد یک مجموعه از زیر شاخه های یک عنصر را به صورت لیست برمیگرداند. گره های موجود در لیست با اعداد (اندیس) قابل دسترسی هستند. اندیس ها از صفر شروع میشوند. برای مثال:
<ul> <li>Coffee</li> <li>Tea</li> </ul> <p>Click the button to change the text of the first list item (index 0).</p> <button onclick="myFunction()">Try it</button> <script> function myFunction() { var list = document.getElementsByTagName("UL")[0]; list.getElementsByTagName("LI")[0].innerHTML = "Milk"; } </script>
در تکه کد فوق ابتدا به اندیس ۰ از لیست اشاره شده و در متغیر ذخیره شده است. سپس با یک محتوای جدید جایگزین شده است.
درصورتی که چندین عنصر از یک نوع داشته باشیم و بخواهیم به همه آنها دسترسی داشته باشیم به صورت زیر عمل میکنیم:
var oImgs = document.getElementsByTagName("img");
در این دستور یک لیست از تمامی عنصرهای img در متغیر ذخیره میشود.
اگر بخواهیم به تمامی عناصر موجود در یک صفحه دسترسی داشته باشیم داریم:
var oAllElements = document.getElementsByTagName("*");
کاراکتر * به منظور انتخاب همه استفاده میشود.
()getElementById
این متد پرکاربردترین و رایج ترین روش برای دسترسی به گره یا عنصر ها استفاده میشود. همانطور که میدانید خاصیت آیدی (ID) باید یکتا باشد؛ یعنی نباید دو عنصر دارای یک آیدی باشند. به همین دلیل است که استفاده از این متد بسیار راحتتر و سریعتر است.
به طور کلی از این متد به صورت زیر استفاده میشود:
document.getElementById
از این متد بیشتر برای چاپ خروجی نیز استفاده میشود. برای مثال:
<button onclick="myFunction()">Try it</button> <p id="demo"></p> <script> function myFunction() { document.getElementById("demo").innerHTML = "Hello World"; } </script>
همچنین شما میتوانید با استفاده از این متدصفت یک عنصر را تغییر دهید. برای مثال:
<p id="demo">Click the button to change the color of this paragraph.</p> <button onclick="myFunction()">Try it</button> <script> function myFunction() { var x = document.getElementById("demo"); x.style.color = "red"; } </script>
()getElementsByName
این متد همانند متد getElementById عمل میکند با این تفاوت که به جای آیدی (ID) از ویژگی نام (name) استفاده میشود. از آنجایی که در html ویژگی name دیگر منسوخ شده است از این متد دیگر استفاده نمیشود.
دسترسی به صفات عناصر
DOM برای دسترسی و همچنین ویرایش صفت های یک عنصر سه متد معرفی کرده است که در ادامه به آنها اشاره میکنیم:
- ()getAttribute : نام کلاس گره مورد نظر را برمیگرداند. برای مثال:
<h1 class="democlass">Hello World</h1> <button onclick="myFunction()">Try it</button> <script> function myFunction() { var x = document.getElementsByTagName("H1")[0].getAttribute("class"); alert(x); } </script>
- ()setAttribute : صفت جدید که تعیین میکنید جایگزین صفت قبلی میکند.برای مثال:
<head> <style> .democlass { color: red; } </style> </head> <body> <h1>Hello World</h1> <button onclick="myFunction()">Try it</button> <script> function myFunction() { document.getElementsByTagName("H1")[0].setAttribute("class", "democlass"); } </script> </body>
- ()removeAttribute : صفت تعیین شده را از عنصر مورد نظر پاک میکند. برای مثال:
<head> <style> .democlass { color: blue; } </style> </head> <body> <h1 class="democlass">Hello World</h1> <button onclick="myFunction()">Try it</button> <script> function myFunction() { document.getElementsByTagName("H1")[0].removeAttribute("class"); } </script> </body>
ایجاد گره جدید
DOM در جاوا اسکریپت کاربردهای بسیار فراوانی دارد. شما حتی میتوانید از متدهای DOM برای ایجاد و حذف گره ها استفاده کنید. همچنین میتوانید گره ها را جابه جا کنید و دیگر دستکاری ها را انجام دهید.
برای ایجاد یک گره جدید از چند متد میتوانید استفاده کنید:
- ()createAttribute : برای ایجاد یک صفت جدید استفاده میشود. برای مثال:
<a id="myAnchor">A Link: Go to programstore.ir</a> <button onclick="myFunction()">Try it</button> <script> function myFunction() { var anchor = document.getElementById("myAnchor"); var att = document.createAttribute("href"); att.value = "https://programstore.ir"; anchor.setAttributeNode(att); } </script>
همانطور که میبینید به یک متن صفت لینک داده شده است.
- ()createComment : برای ایجاد یک توضیح استفاده میشود. اما در صفحه وب نمایش داده نمیشود.
var c = document.createComment("My personal comments"); document.body.appendChild(c);
- ()createElement : برای ایجاد یک عنصر جدید استفاده میشود. برای مثال:
<button onclick="myFunction()">Try it</button> <script> function myFunction() { var para = document.createElement("P"); para.innerText = "This is a paragraph."; document.body.appendChild(para); } </script>
- ()createTextNode : برای ایجاد یک گره از نوع متن ساده استفاده میشود. برای استفاده از این متد ابتدا باید از متد createElement برای ایجاد یک زیر شاخه و سپس از متد element.appendChild برای اضافه کردن گره به یک عنصر استفاده میشود. برای درک بهتر به مثال زیر توجه کنید:
<button onclick="myFunction()">Try it</button> <script> function myFunction() { var h = document.createElement("H1"); var t = document.createTextNode("Hello World"); h.appendChild(t); document.body.appendChild(h); } </script>
متد ()appendchild.
از این متد برای اضافه کردن یک گره به عنوان آخرین فرزند یک گروه استفاده میشود. با استفاده از این متد میتوانید متن ساده ای را به هر گره دلخواهی اضافه نمایید. برای مثال:
<button onclick="myFunction()">Try it</button> <script> function myFunction() { var x = document.createElement("P"); var t = document.createTextNode("This is a paragraph."); x.appendChild(t); document.body.appendChild(x); } </script>
ویژگی innerHTML
این ویژگی محتوای HTML یک عنصر را تنظیم میکند و یا برمیگرداند. برای مثال:
<p id="myP">This is a p element.</p> <div id="myDIV">This is a div element.</div> <script> document.getElementById("myP").innerHTML = "Hello."; document.getElementById("myDIV").innerHTML = "How are you?"; </script>
همانطور که میبینید محتویات داخل بند و پاراگراف با استفاده از ویژگی innerHTML تغییر کرده است.
نکته : این ویژگی جزء استانداردهای W3C نمیباشد اما همه ی مرورگر ها از آن پشتیبانی میکنند.
حذف گره ها
اگر امکان ایجاد گره جدید وجود داشته باشد پس طبیعتاً امکان حذف گره ها نیز وجود خواهد داشت. برای حذف گره ها سه متد وجود دارد که در ادامه به معرفی همراه با مثال خواهیم پرداخت:
- ()removeChild : از این متد برای حذف گره ها استفاده میشود. نحوه کار این متد به این صورت است که با استفاده از یکی از متدهای getElement مشخص میشود کدام گره میخواهید حذف شود و سپس با استفاده از متد removeChild گره مورد نظر حذف خواهد شد. برای مثال به تکه کد زیر توجه کنید:
<ul><li>Coffee</li><li id="myLI">Tea</li><li>Milk</li></ul> <button onclick="myFunction()">Try it</button> <script> function myFunction() { var item = document.getElementById("myLI"); item.parentNode.removeChild(item); } </script>
در این تکه کد ابتدا به هرکدام از گره ها یک آیدی داده شده است و سپس با استفاده از آیدی، گره مورد نظر حذف میشود.
مثال دیگر برای متد removeChild :
<ul id="myList"> <li id="myLI">Coffee</li> </ul> <button onclick="removeLi()">Remove li</button> <button onclick="appendLi()">Insert li</button> <script> var item = document.getElementById("myLI"); function removeLi() { item.parentNode.removeChild(item); } function appendLi() { var list = document.getElementById("myList"); list.appendChild(item); } </script>
در این مثال هم ابتدا همانند مثال قبل میتوان یک گره را حذف و بعد با استفاده از متد appendChild دوباره میتوان گره حذف شده را الحاق کرد.
- ()replaceChild : همانطور که از نام متد پیداست، از این متد برای جایگزین کردن یک گره با گره دیگر استفاده کرد. برای مثال:
<ul id="myList"><li>Coffee</li><li>Tea</li><li>Milk</li></ul> <button onclick="myFunction()">Try it</button> <script> function myFunction() { var textnode = document.createTextNode("Water"); var item = document.getElementById("myList").childNodes[0]; item.replaceChild(textnode, item.childNodes[0]); } </script>
در مثال بالا ابتدا یک لیست تشکیل داده و سپس با استفاده از ویژگی getElementById و اندیس گره مورد نظر در لیست، گره مورد نظر با یک گره جدید جایگزین شده است.
- ()insertBefore : برای اضافه کردن یک گره به قبل از گره دیگر از این متد استفاده میشود. همچنین از این متد میتوان برای حرکت دادن یک گره موجود در لیست استفاده کنید. برای مثال:
<ul id="myList1"><li>Coffee</li><li>Tea</li></ul> <ul id="myList2"><li>Water</li><li>Milk</li></ul> <button onclick="myFunction()">Try it</button> <script> function myFunction() { var node = document.getElementById("myList2").lastChild; var list = document.getElementById("myList1"); list.insertBefore(node, list.childNodes[0]); } </script>
در این مثال دو لیست داریم که گره های لیست دوم با استفاده از متد lastChild انتخاب میشوند و سپس با استفاده از متد insertBefore به ابتدای لیست اول اضافه میشود.
متد ()createDocumentFragment
زمانی که شما تعدادی گره به سند اضافه کنید، برای اینکه تغییرات نمایش داده شوند صفحه بروزرسانی خواهد شد. در صورتی که تعداد تغییرات زیاد باشد و صفحه برای نمایش دادن تغییرات بخواهد بروز رسانی شود، در عملکرد مرورگر با کندی سرعت مواجه خواهید شد.
برای اینکه بتوانید از این مشکل دوری کنید ابتدا باید از متد createDocumentFragment استفاده کنید. استفاده از این متد و اضافه کردن همه گره های جدید به برنامه باعث میشود تا بروزرسانی تنها یک بار انجام شده و همه تغییرات نمایش داده شود.
بدین صورت که یک تکه برنامه مینویسیم و همه گره های جدید را به برنامه اضافه میکنیم و سپس تنها کاری که باید انجام دهیم این است که برنامه را در صفحه اصلی قرار دهیم.
برای مثال به تکه کد زیر توجه کنید:
var arrText = ["first", "second", "third", "fourth", "fifth", "sixth"]; var oFragment = document.createDocumentFragment(); for (var i=0; i < arrText.length; i++) { var oP = document.createElement("p"); var oText = document.createTextNode(arrText[i]); oP.appendChild(oText); oFragment.appendChild(oP); } document.body.appendChild(oFragment);
در مثال بالا ما یک آرایه داریم و میخواهیم و اساس هر یک از مقادیر یک پاراگراف <p> ایجاد کنیم. بنابراین یک متغیر تعریف کردیم و با استفاده از حلقه for سرعت مرورگر را بهینه کردیم.
ویژگی های منحصر به فرد DOM برای HTML
DOM در جاوا اسکریپت همانطور که ار نام کامل آن پیداست ارتباط مستقیمی با سند دارد. شما میتوانید با استفاده از DOM صفات مربوط به تگ های HTML را نیز تنظیم و یا دستکاری کنید. این کار به این صورت است که صفت های هر تگ به عنوان خاصیت های یک شیء درنظر گرفته میشود. به این ترتیب میتوان با استفاده از متدهایی به صفات دسترسی پیدا کرده و آنها را دستکاری کرد.
برای این کار از متدهای ()getAttribute و ()setAttribute استفاده میشود.
نکته : در صورت استفاده از این روش نمیتوانید از خود صفت class استفاده کنید. زیرا این کلمه جزء کلمات رزرو شده است. به جای آن میتوانید از className استفاده کنید.
چنانچه تصمیم به ارائه در زمینه HTML دارید میتوانید به فایل موجود در لینک زیر مراجعه کنید.
دستکاری قواعد سبک (style) عناصر
همانطور که میدانید در HTML برای دادن صفت به عناصر از شیء style استفاده میشود. همچنین در جاوا اسکریپت برای دسترسی به گره های صفتی از یک شیء به نام style استفاده میشود. دستور کلی بدین صورت است:
document.getElementById('id').style.property="newValue";
برای مثال دستور زیر باعث خواهد شد تا یک متن با آیدی demo به رنگ قرمز تغییر کند:
document.getElementById('demo').style.color="red";
همچنین در جاوا اسکریپت برای دسترسی به آن قواعد که دارای کاراکتر (-) هستند، (مانند background-color یا padding-top) ابتدا باید کاراکتر (-) را حذف کنید و سپس اولین حرف کلمه های بعدی آن را به صورت بزرگ بنویسیم. مانند:
background-color ==> backgroundColor border-top-width ==> borderTopWidth
متدهای مربوط به جداول
در ادامه پست آموزشی DOM در جاوا اسکریپت با ما همراه باشید. اگر بخواهیم یک جدول در HTML ایجاد کنیم تنها کافی است که به صورت زیر عمل کنیم :
<table border="1" width="100%"> <tbody> <tr> <td>Cell 1,1</td> <td>Cell 2,1</td> </tr> <tr> <td>Cell 1,2</td> <td>Cell 2,2</td> </tr> </tbody> </table>
حال اگر بخواهیم همین جدول را با استفاده از جاوا اسکریپت طراحی کنیم چه کار باید کرد؟ اگر بخواهیم از متدهای رایج DOM برای این کار استفاده کنیم مجبور به نوشتن دستورات طولانی زیر خواهیم بود که در اکثر موارد سردرگم کننده است:
//create the table var oTable = document.createElement("table"); oTable.setAttribute("border", "1"); oTable.setAttribute("width", "100%"); //create the tbody var oTBody = document.createElement("tbody"); oTable.appendChild(oTBody); //create the first row var oTR1 = document.createElement("tr"); oTBody.appendChild(oTR1); var oTD11 = document.createElement("td"); oTD11.appendChild(document.createTextNode("Cell 1,1")); oTR1.appendChild(oTD11); var oTD21 = document.createElement("td"); oTD21.appendChild(document.createTextNode("Cell 2,1")); oTR1.appendChild(oTD21); //create the second row var oTR2 = document.createElement("tr"); oTBody.appendChild(oTR2); var oTD12 = document.createElement("td"); oTD12.appendChild(document.createTextNode("Cell 1,2")); oTR2.appendChild(oTD12); var oTD22 = document.createElement("td"); oTD22.appendChild(document.createTextNode("Cell 2,2")); oTR2.appendChild(oTD22); //add the table to the document body document.body.appendChild(oTable);
برای جلوگیری از این سردرگمی DOM چند متد و چند خاصیت ایجاد کرده است که شامل عنصرهای اصلی یک جدول مانند table، tbody، tr میشود. در ادامه به معرفی این متدها و خاصیت ها میپردازیم:
خاصیت های table
- caption : درصورتی که جدول caption (عنوان) داشته باشد، عنصر caption را برمیگرداند.
- tBodies : مجموعه ای از تمام عناصر tbody را در جدول برمی گرداند.
- tFoot : عنصر tfoot را برمیگرداند.
- tHead :عنصر thead را برمیگرداند.
- Rows : مجموعه ای از تمام ردیف را در جدول برمی گرداند.
متد های table
- ()createThead : یک عنصر thead خالی ایجاد می کند و آن را به جدول اضافه می کند.
- ()createTfoot : یک عنصر tfoot خالی ایجاد می کند و آن را به جدول اضافه می کند.
- ()createCaption : یک عنصر caption خالی ایجاد می کند و آن را به جدول اضافه می کند.
- ()createThead : یک عنصر tfoot خالی ایجاد می کند و آن را به جدول اضافه می کند.
- ()deleteTfoot :عنصر tfoot (و محتوای آن) را از جدول حذف می کند.
- ()deleteCaption : عنصر caption (و محتوای آن) را از جدول حذف می کند.
- ()deleteRow : سطر را در شاخص مشخص شده از جدول حذف می کند.
- ()insertRow : یک عنصر tr خالی ایجاد می کند و آن را به جدول اضافه می کند.
حال اگر بخواهیم با استفاده از متدهای بالا جدول قبلی را ایجاد کنیم تنها کافیست به صورت زیر عمل کنیم:
//create the table var oTable = document.createElement("table"); oTable.setAttribute("border", "1"); oTable.setAttribute("width", "100%"); //create the tbody var oTBody = document.createElement("tbody"); oTable.appendChild(oTBody); //create the first row oTBody.insertRow(0); oTBody.rows[0].insertCell(0); oTBody.rows[0].cells[0].appendChild(document.createTextNode("Cell 1,1")); oTBody.rows[0].insertCell(1); oTBody.rows[0].cells[1].appendChild(document.createTextNode("Cell 2,1")); //create the second row oTBody.insertRow(1); oTBody.rows[1].insertCell(0); oTBody.rows[1].cells[0].appendChild(document.createTextNode("Cell 1,2")); oTBody.rows[1].insertCell(1); oTBody.rows[1].cells[1].appendChild(document.createTextNode("Cell 2,2")); //add the table to the document body document.body.appendChild(oTable);
سخن آخر درباره آموزش جاوا اسکریپت
در این پست از آموزش های پیاستور در رابطه با DOM در جاوا اسکریپت صحبت کردیم. DOM که مخفف Document Object Model میباشد عناصر موجود در یک سند را تجزیه و تحلیل میکند و آنها را به صورت یک ساختار درختی نمایش میدهد.
در این پست یاد گرفتیم که چگونه به عناصر موجود در HTML دسترسی داشته باشیم و آنها را دستکاری کنیم. شما میتوانید در ادامه مجموعه پست های آموزشی هرچه بیشتر در رابطه با جاوا اسکریپت یاد بگیرید. در پست بعدی در رابطه کار با فرم ها و عناصر فرم صحبت خواهیم کرد. منتظر نظرات و پیشنهادات شما هستیم. موفق باشید.