من مترجم: ديفيد جيلبرتسون مؤلف معروف يكتب عن تقنيات الويب والعملات المشفرة. كان قادرًا على جمع جمهور كبير من القراء ، والذي يحكي عن جميع أنواع الحيل والمناطق المثيرة للاهتمام.
مقدمة صغيرةدعونا نناقش الفرق بين HTML و DOM.
على سبيل المثال ، خذ عنصر
الجدول من HTML. يمكنك استخدامه في ملف بامتداد html. في ذلك ، نشير إلى مجموعة من السمات التي تحدد مظهر الصفحة و "سلوكها".
هذا كل شيء ، لا علاقة لجافا سكريبت.
DOM هو شيء يسمح لك بدمج كود JavaScript الخاص بك مع عناصر HTML في وثيقة بحيث يمكنك التفاعل معها ككائنات.
هذا نموذج مستند في كائن.
أي نوع من العناصر في HTML له واجهة "DOM" خاصة به ، والتي تحدد الخصائص والأساليب. على سبيل المثال ، يحتوي
الجدول على واجهة تسمى
HTMLTableElement .
يمكنك الحصول على رابط لعنصر معين عن طريق كتابة شيء مثل هذا:

لديك حق الوصول إلى جميع الخصائص والأساليب المتوفرة لنوع معين من العناصر. على سبيل المثال ، يمكنك الوصول إلى خصائص القيمة باستخدام searchBox.value ، أو تعيين المؤشر إلى موضع معين باستخدام searchBox.focus ().
دعنا الآن نناقش شيئًا أكثر أهمية: معظم العناصر ليس لديها طرق مثيرة للاهتمام ، لذلك من السهل تفويت شيء مهم إذا لم تتعمق في هذه المشكلة عن قصد.
ولكن ، لحسن الحظ ، فإن الاهتمام بالتفاصيل ودراسة المواصفات هو موطن قوتي. لذلك ، فعلت كل ما هو ضروري وكتبت عن النتائج في هذه المقالة.
إذا كنت ترغب في محاولة التعامل مع DOM بنفسك ، يجب عليك استخدام أدوات المتصفح لتعلم بعض العناصر. للقيام بذلك ، حدد أحدها في شجرة العناصر واكتب $ 0 في وحدة التحكم. سيمنحك هذا رابطًا إلى العنصر الذي حددته. لتحويله إلى كائن ، اكتب dir ($ 0).
هناك العديد من الأشياء
التي يمكنك القيام بها في وحدة التحكم .

توصي Skillbox بما يلي: دورة عبر الإنترنت لمطوري الويب
نذكركم: لجميع قراء هبر - خصم 10000 روبل عند التسجيل في أي دورة من دورات Skillbox باستخدام كود هبر الترويجي.
رقم 1. طرق الجدول
هناك العديد من الطرق الملائمة التي تسمح لك بتجميع الطاولات مثل الأثاث في ايكيا.
const tableEl = document.querySelector('table'); const headerRow = tableEl.createTHead().insertRow(); headerRow.insertCell().textContent = 'Make'; headerRow.insertCell().textContent = 'Model'; headerRow.insertCell().textContent = 'Color'; const newRow = tableEl.insertRow(); newRow.insertCell().textContent = 'Yes'; newRow.insertCell().textContent = 'No'; newRow.insertCell().textContent = 'Thank you';
هنا ترى ليس فقط document.createElement (). على سبيل المثال ، ستقوم طريقة .insertRow ()
بتضمين tbody إذا قمت بتنظيم استدعاء لهذا العنصر مباشرة في الشجرة. أليس هذا رائعا؟
رقم 2. التمرير إلى ViewView ()
هل تعلم أنه إذا كان لديك # شيء في عنوان URL ، فعندما يتم تحميل الصفحة ، سينتقل المتصفح إلى العنصر الذي يحمل هذا المعرف؟
عادة ما يساعد هذا كثيرًا ، لكنه لا يعمل إذا قمت بعرض هذا العنصر بعد تحميل الصفحة. من أجل الاستفادة من الفرصة الموضحة أعلاه ، ما عليك سوى تحديد document.querySelector (document.location.hash) .scrollIntoView () ؛
رقم 3. مخفي
حسنًا ، نعم ، إنها نوعًا ما مثل طريقة ، ولكن نظرًا لوجود أداة ضبط (طريقة لتعيين خاصية) ، فيمكن اعتبارها طريقة.
مع ذلك ، هل سبق لك أن استخدمت myElement.style.display = 'none' لإخفاء عنصر؟ إذا كان الأمر كذلك ، فلا تفعل ذلك.
حيث من الأفضل استخدام myElement.hidden = true.
رقم 4. تبديل ()
يمكننا استخدام هذه الطريقة لإضافة أو إزالة فئة عنصر باستخدام myElement.classList.toggle ("بعض الفئات").
وإذا سبق لك أن قمت بإضافة فصل دراسي باستخدام إذا ، فكر: ربما يجب عليك تجربة شيء آخر؟
على سبيل المثال ، يمكنك ببساطة استخدام المعلمة الثانية لأسلوب التبديل. تحتاج إلى تمريرها إلى طريقة التبديل. إذا حدث ذلك ، ستتم إضافة فصلك إلى العنصر:
el.classList.toggle('some-orange-class', theme === 'orange');
نعم ، أفهم ما تفكر فيه الآن: ليس هذا ما تعنيه كلمة "toogle" نفسها. أولئك الذين يقفون وراء Internet Explorer؟ نتفق مع هذا ونعبر عن احتجاجهم دون استخدام المعلمة الثانية على الإطلاق.
لكن دعنا نعيده. الحرية للخيارات!
رقم 5. querySelector ()
حسنًا ، يجب أن تعرف هذا بالتأكيد ، لكني أشك في أن حوالي 17 ٪ من القراء لا يدركون كيف يمكن استخدام هذه الطريقة مع العناصر.
مثال: سوف يعرض myElement.querySelector ('. My-class') مراسلات العناصر التي تحتوي على فئة صفي و "أطفال" myElement.
رقم 6. الأقرب
هذه الطريقة متاحة لجميع العناصر التي تعرض شجرة العناصر. يعد هذا نوعًا من التراجع عن querySelector (). لذلك ، يمكننا استخدام عنوان القسم الحالي بهذه الطريقة:
myElement.closest('article').querySelector('h1');
نبدأ
بالمقال وننتهي بـ h1 الأول.
رقم 7. getBoundingClientRect ()
تقوم الطريقة بإرجاع كائن بمعلومات تفصيلية حول العنصر الذي حددناه.
{ x: 604.875, y: 1312, width: 701.625, height: 31, top: 1312, right: 1306.5, bottom: 1343, left: 604.875 }
ولكن كن حذرا: هذا المثال يسبب إعادة رسم. اعتمادًا على الجهاز وتعقيد صفحتك ، قد يستغرق ذلك عدة أجزاء من الثانية. لذلك ، ضع هذا في الاعتبار إذا كنت تسميها بشكل متكرر ، على سبيل المثال في الرسوم المتحركة.
لا تعرض جميع المتصفحات كل هذه القيم.
رقم 8. مباريات ()
أود التحقق مما إذا كان عنصر معين ينتمي إلى فئة معينة.
الصعوبة القصوى:
if (myElement.className.indexOf('some-class') > -1) { // do something } , : if (myElement.className.includes('some-class')) { // do something }
ما تحتاجه:
if (myElement.matches('.some-class')) {
رقم 9. insertAdjacentElement ()
اكتشفته اليوم! يشبه هذا appendChild () ، ولكنه يمنح المزيد من التحكم في عملية إضافة الطفل.
motherEl.insertAdjacentElement ('beforeend' ، newEl) يفعل نفس الشيء تمامًا مثل motherEl.appendChild (newEl) ، ولكن يمكنك تحديد قبل ، أو بعد ترقيمه أو بعده لوضعه في المكان الذي تشير إليه هذه الأسماء.
كم التحكم!
رقم 10. يحتوي على ()
هل سبق لك أن أردت معرفة ما إذا كان هناك عنصر داخل عنصر آخر؟ أريد أن أعرف هذا طوال الوقت.
على سبيل المثال ، إذا تعاملت مع نقرة بالماوس وأردت أن أفهم ما إذا كان قد حدث من الداخل أو من الخارج (حتى أتمكن من إغلاقه) ، أفعل ذلك:
const handleClick = e => { if (!modalEl.contains(e.target)) modalEl.hidden = true; };
هنا مشروط El هو إشارة إلى النافذة المشروطة ، و e.target هو العنصر الذي يجب النقر عليه.
إنه أمر مضحك ، لكنني غالبًا ما أرتكب أخطاء في المنطق عندما أحاول استخدام الطريقة في المرة الأولى. ثم عندما أحاول إصلاح الخطأ ، فأنا مخطئ مرة أخرى. وهذه الطريقة تساعد على التعامل معها على الفور.
رقم 11. getAttribute ()
واحدة من أكثر الطرق غير المجدية للعناصر ، ولكن ليس في هذه الحالة بالذات.
هل تتذكر أن الخصائص عادة ما تشير إلى السمات؟
في بعض الأحيان لا يكون هذا هو الحال ، على سبيل المثال ، عندما يكون href صفة لعنصر ، على سبيل المثال a href = "/ Animals / cat"> Cat </ a.
el.href لن يعطينا / حيوانات / قط ، كما تتوقع. وذلك لأن العنصر يطبق واجهة HTMLHyperlinkElementUtils ، وهي عبارة عن مجموعة من خصائص المساعد مثل البروتوكول والتجزئة التي تشير إلى كائن الارتباط.
هذه واحدة من خصائص href المفيدة التي ستعطي L الكامل ، وليس عنوان URL النسبي في السمة.
لذلك يجب عليك استخدام el.getAttribute ('href') إذا كنت بحاجة إلى سلسلة حرفية داخل سمة href.
رقم 12. الحوار
يحتوي عنصر
الحوار الجديد نسبيًا على طريقتين جيدتين وواحد مثالي. إظهار () وإغلاق () فعل ما هو متوقع منهم بالضبط. وهذا أمر جيد ، على ما أفترض.
لكن showModal () سيعرض
مربع حوار أعلى أي عناصر أخرى توضع على الصفحة. ليست هناك حاجة لفهرس z ، أو إضافة خلفية معتمة يدويًا ، أو تتبع الضغط على زر Escape. يعرف المتصفح كيفية عمل النوافذ المشروطة وسيفعل كل شيء من أجلك. وهذا رائع.
رقم 13. لكل ()
في بعض الأحيان ، عندما تحتاج إلى مرجع لقائمة العناصر ، يمكنك استخدام forEach ().
ولكن ماذا لو كنت بحاجة إلى تسجيل جميع عناوين URL لجميع روابط الصفحة؟ يمكنك القيام بذلك ورؤية الخطأ.
document.getElementsByTagName('a').forEach(el => { console.log(el.href); });
أو قم بذلك:
document.querySelectorAll('a').forEach(el => { console.log(el.href); });
النقطة هي أن getElementsByTagName وطرق get أخرى ... تُرجع HTMLCollection ، لكن querySelectorAll تُرجع NodeList.
وتعطينا واجهة NodeList طريقة forEach () (جنبًا إلى جنب مع المفاتيح () والقيم () والمدخل ()).
أعطانا الأخيار من ECMA Array.from () ، الذي يحول كل شيء يشبه المصفوفة إلى المصفوفة نفسها.
Array.from(document.getElementsByTagName('a')).forEach(el => { console.log(el.href); });
مكافأة! عند إنشاء مصفوفة ، يمكنك استخدام map () و filter () وتقليل () أو أي طريقة أخرى. على سبيل المثال ، عرض مصفوفة من الروابط الخارجية:
Array.from(document.querySelectorAll('a')) .map(el => el.origin) .filter(origin => origin !== document.origin) .filter(Boolean);
أحب حقًا أن أصف .filter (Boolean) ، لأنه بدونه سأضطر إلى خدش رأسي في المستقبل ، محاولًا تذكر ما هو وكيف يعمل.
رقم 14. النماذج
النموذج ، كما تعلم على الأرجح ، يحتوي على طريقة إرسال (). أقل احتمالية إلى حد ما أنك تعرف أن النماذج بها طريقة إعادة تعيين () ويمكنها الإبلاغ عن قيمة Validity () إذا كنت تستخدم التحقق من الصحة في عناصر النموذج.
يمكنك أيضًا استخدام خاصية ترميز النقاط لعناصر النموذج للإشارة إلى عنصر بواسطة سمة الاسم. على سبيل المثال ، سيعيد myFormEl.elements.email
اسم الإدخال = عنصر
"email" / الذي ينتمي إلى
النموذج ("ينتمي" لا يعني بالضرورة أنه "سليل").
والآن كذبت. الحقيقة هي أن العناصر لا تُرجع قائمة بالعناصر. تقوم بإرجاع قائمة عناصر التحكم (وبطبيعة الحال ، هذه ليست صفيف).
مثال: إذا كان لديك ثلاثة أزرار اختيار ، لكل منها نفس اسم الحيوان ، فسوف يمنحك formEl.elements.animal رابطًا لهذه المجموعة من أزرار الاختيار (عنصر تحكم واحد ، 3 عناصر).
وستُرجع formEl.elements.animal.value قيمة زر الاختيار المحدد.
هذه بنية غريبة ، إذا فكرت في الأمر. قسّمها يا شباب: formEl عنصر ، والعناصر هي HTMLFormControlsCollection ، وليست صفيفًا تمامًا ، حيث لا يكون كل عنصر بالضرورة عنصر HTML. يحتوي Animal على العديد من مفاتيح التبديل مجتمعة فقط لأن لديهم نفس سمة الاسم (هناك واجهة RadioNodeList لهذا) ، وتبحث القيمة من خلال سمة القيمة لأي محول في المجموعة.
رقم 15. حدد ()
ستحدد طريقة .select () كل النص في أي إدخال تتصل به.
شكرا للقراءة ، آمل أن يكون كل هذا مفيدا لك. تحقق دائمًا من إمكانات متصفحك حتى لا يكون مؤلمًا بشكل مؤلم.
عملي من Skillbox ، والذي سيساعد المبرمج المبتدئ ليصبح متخصصًا مطلوبًا :