15 خصائص وطرق غير معروفة لكائنات DOM

عند تطوير مواقع الويب الحديثة ، يتم استخدام ميزات JavaScript للعمل مع DOM بكثافة. تسمح لك البرامج النصية بعرض وإخفاء العناصر التي تم إنشاء الصفحات منها ، وتكوين خصائص هذه العناصر. كائنات DOM التي يتم التفاعل معها من البرامج لها خصائص وأساليب. عمليا ، يعرف جميع مبرمجي الويب عن بعضهم ، وفقا لمؤلف المادة ، التي ننشر ترجمتها اليوم. لكن البعض الذي يريد التحدث عنه هنا أقل شهرة بكثير.



HTML و DOM


أولاً ، لنتحدث عن الفرق بين HTML و DOM. على سبيل المثال ، من الواضح أن عنصر <table< العادي هو رمز HTML. يمكن استخدام هذا العنصر في ملفات html ، ولديه مجموعة من السمات التي تحدد مظهر وسلوك الجدول الذي تم إنشاؤه بمساعدته. بالمعنى الدقيق للكلمة ، علامة <table> نفسها لا علاقة لها بجافا سكريبت. يتم توفير العلاقة بين عناصر HTML الموجودة في المستند ورمز JavaScript بواسطة DOM (نموذج كائن المستند). يتيح DOM إمكانية التفاعل مع عناصر HTML من كود JavaScript كما لو كانت كائنات.

تحتوي جميع عناصر HTML على "واجهات DOM" الخاصة بها والتي تحدد الخصائص (ترتبط عادةً بسمات عناصر HTML) والأساليب. على سبيل المثال ، يحتوي عنصر <table> على واجهة تسمى HTMLTableElement .

يمكنك الحصول على رابط لعنصر ، على سبيل المثال ، باستخدام البناء التالي:

 const searchBox = document.getElementById('search-box'); 

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

ربما هذا هو المكان الذي يمكننا فيه إكمال "الدورة التدريبية القصيرة على DOM" والانتقال ، في الواقع ، إلى الخصائص والأساليب غير المعروفة لواجهات DOM لعناصر HTML.

إذا كنت تريد القراءة والتجربة على الفور ، فافتح أدوات مطور المتصفح. على وجه الخصوص ، من أجل الحصول على رابط لعنصر صفحة معين ، يمكنك تحديده في شجرة العناصر ، ثم استخدام البناء $0 في وحدة التحكم . لعرض عنصر ككائن ، اكتب dir($0) في وحدة التحكم. وبالمناسبة ، إذا عثرت على شيء جديد بالنسبة لك ، فحاول استكشافه باستخدام وحدة التحكم.

رقم 1: طرق الجدول


يحتوي عنصر <table> المتواضع (الذي لا يزال يحتل المرتبة الأولى بين التقنيات المستخدمة في تطوير تخطيطات صفحات الويب) على عدد لا بأس به من الطرق الجيدة للغاية التي تبسط عملية إنشاء الجداول بشكل كبير.

هنا بعض منهم.

 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() طريقة .insertRow() ، إذا قمت .insertRow() مباشرة على الطاولة ، إضافة <tbody> . أليست رائعة؟

# 2: طريقة الستالينيتفيو ()


ربما تعرف أنه إذا كان الرابط يحتوي على بنية مثل #something ، فبعد تحميل الصفحة ، سينتقل المتصفح تلقائيًا إلى العنصر ID المقابل؟ الطريقة مناسبة ، ولكن إذا تم تقديم العنصر الذي يهمك بعد تحميل الصفحة ، فلن تعمل. إليك كيفية إعادة إنشاء هذا النمط السلوكي بنفسك:

 document.querySelector(document.location.hash).scrollIntoView(); 

رقم 3: الممتلكات المخفية


هنا نعتبر خاصية ، على الأرجح ، عند الوصول إلى هذه الخاصية ، سيتم استدعاء محدد معين ، وهو أسلوب. على أي حال ، تذكر ، هل سبق لك استخدام التصميم الموضح أدناه لإخفاء عنصر؟

 myElement.style.display = 'none' 

إذا كنت تستخدمه ، فلا يجب عليك فعله بعد الآن. لإخفاء عنصر ما ، اكتب فقط إلى خاصيته hidden :

 myElement.hidden = true 

# 4: طريقة التبديل ()


في الواقع ، هذه ليست طريقة لبعض العناصر. هذا هو أسلوب خاصية العنصر. على وجه الخصوص ، تسمح لك هذه الطريقة بإضافة فئات إلى عنصر وإزالتها منه باستخدام البناء التالي:

 myElement.classList.toggle('some-class') 

بالمناسبة ، إذا سبق لك أن أضفت فئات باستخدام if ، فكن على دراية بأنه ليس عليك القيام بذلك بعد الآن ، ونسيان هذا البناء. يتم تنفيذ الآلية نفسها باستخدام المعلمة الثانية لأسلوب toggle() . إذا كان هذا تعبيرًا يتم تقييمه إلى " true ، فستتم إضافة الفئة التي تم تمريرها toggle() إلى العنصر.

 el.classList.toggle('some-orange-class', theme === 'orange'); 

ربما ، هنا قد يكون لديك شكوك حول كفاية هذا التصميم. بعد كل شيء ، اسم الطريقة ، "تبديل" ، والذي ، بالنظر إلى حقيقة أن جوهر الإجراء الذي يتم تنفيذه مخفيًا فيه ، يمكن ترجمته على أنه "مفتاح تبديل" ، لا يتضمن أي إشارة إلى أن "التبديل" يعني تحقيق شرط معين. ومع ذلك ، فإن التصميم الموضح أعلاه موجود في هذا النموذج ، على الرغم من أن مطوري Internet Explorer ربما يعتبرونه غريبًا أيضًا. في تنفيذهم toggle() لم يتم توفير المعلمة الثانية. لذلك ، على الرغم من أنه قيل أعلاه أن أولئك الذين يعرفون عن toggle() يمكنهم نسيان بناء if ، نسيان ذلك ، مع ذلك ، لا.

# 5: طريقة querySelector ()


من المؤكد أنك تعرف بالفعل عن وجود هذه الطريقة ، ولكن هناك شك في أن 17 ٪ منكم بالضبط لا يعرفون أنه يمكن استخدامها في التطبيق على أي عنصر.

على سبيل المثال ، يحدد البناء myElement.querySelector('.my-class') العناصر التي تحتوي على الفئة my-class في نفس الوقت والتي تكون من نسل عنصر myElement .

# 6: الطريقة الأقرب ()


جميع العناصر التي تدعم البحث عن العنصر الأصلي لها هذه الطريقة. هذا شيء مثل عكس querySelector() . باستخدام هذه الطريقة ، على سبيل المثال ، يمكنك الحصول على عنوان القسم الحالي:

 myElement.closest('article').querySelector('h1'); 

هنا ، أثناء البحث ، يتم أولاً الكشف عن العنصر الرئيسي الأول <article> ، ثم العنصر الأول <h1> يدخله.

# 7: طريقة getBoundingClientRect ()


ترجع طريقة 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) { //  -  } 

هنا خيار آخر ، إنه أفضل ، ولكنه أيضًا بعيد عن المثالية:

 if (myElement.className.includes('some-class')) { //  -  } 

وإليك أفضل طريقة لحل هذه المشكلة:

 if (myElement.matches('.some-class')) { //  -  } 

# 9: طريقة insertAdjacentElement ()


هذه الطريقة تشبه appendChild() ، ولكنها تعطي قوة أكبر قليلاً على المكان الذي ستتم فيه إضافة العنصر الفرعي بالضبط.

لذا ، فإن الأمر parentEl.insertAdjacentElement('beforeend', newEl) يشبه الأمر parentEl.appendChild(newEl) ، ولكن باستخدام طريقة insertAdjacentElement() ، بالإضافة إلى الوسيطة beforeend ، يمكنك تمرير beforebegin و afterbegin و afterend ، مما يشير إلى المكان الذي تحتاج إليه إضافة عنصر.

رقم 10: يحتوي على طريقة ()


هل سبق لك أن أردت معرفة ما إذا كان أحد العناصر داخل عنصر آخر؟ انا احتاجه طوال الوقت على سبيل المثال ، إذا كنت تحتاج أثناء معالجة حدث النقر بالماوس إلى معرفة ما إذا كان قد حدث داخل النافذة المشروطة أو خارجها (مما يعني أنه يمكن إغلاقه) ، يمكنك استخدام البناء التالي:

 const handleClick = e => { if (!modalEl.contains(e.target)) modalEl.hidden = true; }; 

هنا modalEl هو رابط إلى نافذة e.target ، و e.target هو أي عنصر يتم النقر عليه. من المثير للاهتمام ، عندما أستخدم هذه التقنية ، لا يمكنني أبدًا كتابة كل شيء بشكل صحيح في المرة الأولى ، حتى عندما أتذكر أنني مخطئ باستمرار وأحاول إصلاح الأخطاء المحتملة مقدمًا.

رقم 11: طريقة getAttribute ()


ربما يمكن تسمية هذه الطريقة بأنها الأكثر فائدة ، ومع ذلك ، فهناك موقف واحد يمكن أن يكون مفيدًا بالتأكيد.

تذكر ، قلنا سابقًا أن خصائص كائنات DOM عادة ما ترتبط بسمات عناصر HTML؟

إحدى الحالات عندما لا تكون هذه هي الحالة التي يتم تمثيلها بواسطة سمة href ، على سبيل المثال ، مثل هنا: <a href="/animals/cat">Cat</a> .

el.href يعود بناء el.href ، كما هو متوقع ، /animals/cat . وذلك لأن عنصر <a> يطبق واجهة HTMLHyperlinkElementUtils ، التي تحتوي على العديد من خصائص المساعد مثل protocol والتجزئة التي تساعدك على معرفة تفاصيل الروابط.
إحدى خصائص المساعد هذه هي خاصية href ، والتي تقدم عنوان URL كاملًا يتضمن كل شيء لا يحتوي عليه عنوان URL النسبي في السمة.

ونتيجة لذلك ، من أجل الحصول على ما هو مكتوب تمامًا في سمة href ، تحتاج إلى استخدام بناء el.getAttribute('href') .

رقم 12: ثلاث طرق لعنصر <الحوار>


يحتوي عنصر <dialog> الجديد نسبيًا على طريقتين مفيدتين ، لكن عاديتين تمامًا ، وطريقة واحدة يمكن تسميتها ببساطة رائعة. لذا ، فإن طرق show() و close() تفعل بالضبط ما يمكن أن تتوقعه منهم ، وتظهر وتخفي النافذة. نسميها مفيدة ، لكنها عادية. ولكن ستظهر طريقة showModal() عنصر <dialog> فوق كل شيء آخر ، ويعرضه في منتصف النافذة. في الواقع ، عادة ما يتوقع مثل هذا السلوك من النوافذ المشروطة. عند العمل مع هذه العناصر ، لا تحتاج إلى التفكير في خاصية z-index ، أو إضافة خلفية ضبابية يدويًا ، أو الاستماع إلى حدث الضغط على مفتاح Escape لإغلاق النافذة المقابلة. يعرف المستعرض كيفية عمل النوافذ المشروطة وسيتأكد من عمل كل شيء كما ينبغي.

رقم 13: طريقة forEach ()


في بعض الأحيان ، عندما تحصل على ارتباط بقائمة من العناصر ، يمكنك forEach() هذه العناصر باستخدام طريقة forEach() . حلقات for() أمس. افترض أننا بحاجة إلى سرد جميع عناصر <a> من الصفحة الموجودة في السجل. إذا قمنا بذلك كما هو موضح أدناه ، فسوف نواجه رسالة خطأ:

 document.getElementsByTagName('a').forEach(el => {   console.log(el.href); }); 

من أجل حل هذه المشكلة ، يمكنك استخدام البناء التالي:

 document.querySelectorAll('a').forEach(el => {   console.log(el.href); }); 

النقطة هنا هي أن أساليب مثل getElementsByTagName() تُرجع كائنًا من نوع HTMLCollection ، وأن querySelectorAll كائن querySelectorAll . وهي واجهة كائن NodeList تتيح لنا الوصول إلى طريقة forEach() (وكذلك إلى keys() ، values() وطرق entries() ).

في الواقع ، سيكون من الأفضل بكثير إذا أعادت هذه الأساليب المصفوفات العادية ببساطة ، ولم تقدم لنا شيئًا يحتوي على نوع من الطرق المفيدة على ما يبدو والتي لا تشبه المصفوفات تمامًا. ومع ذلك ، لا تنزعج بسبب هذا ، لأن الأشخاص الأذكياء من ECMA قدموا لنا طريقة رائعة - Array.from() ، والتي تسمح لنا بتحويل كل ما يشبه المصفوفات إلى صفائف.

ونتيجة لذلك ، يمكنك كتابة ما يلي:

 Array.from(document.getElementsByTagName('a')).forEach(el => {   console.log(el.href); }); 

وهنا شيء صغير لطيف. من خلال التحويل إلى صفيف ما كان يشبهه تمامًا ، نحصل على فرصة لاستخدام العديد من طرق الصفيف ، مثل map() filter() reduce() . هنا ، على سبيل المثال ، كيفية تكوين صفيف من الارتباطات الخارجية على الصفحة:

 Array.from(document.querySelectorAll('a')) .map(el => el.origin) .filter(origin => origin !== document.origin) .filter(Boolean); 

بالمناسبة ، أنا معجب حقًا .filter(Boolean) لأنه عندما ألتقي بها في وقت ما في الرمز الذي كتبته منذ فترة طويلة ، بالكاد أستطيع فهم معناه.

رقم 14: العمل مع النماذج


من المحتمل جدًا أن تعرف أن عنصر <form> يحتوي على طريقة submit() . ومع ذلك ، من غير المحتمل أن تعرف أن النماذج تحتوي على طريقة reset() ، وأن لديها طريقة reportValidity() ، والتي تكون قابلة للتطبيق عند استخدام التحقق من ملء عناصر النموذج.

عند العمل مع النماذج ، بالإضافة إلى ذلك ، يمكنك استخدام خاصية elements الخاصة بها ، والتي تسمح لك ، من خلال نقطة ، بالوصول إلى عناصر النموذج باستخدام سمات name الخاصة بهم. على سبيل المثال ، myFormEl.elements.email بنية myFormEl.elements.email <input name="email" /> ينتمي إلى النموذج ("تعني" " myFormEl.elements.email " لا يعني بالضرورة أن تكون سليلًا).

وتجدر الإشارة هنا إلى أن خاصية elements نفسها لا تُرجع قائمة بالعناصر العادية. تقوم بإرجاع قائمة عناصر التحكم (وهذه القائمة بالطبع ليست صفيف).

هنا مثال. إذا كان هناك ثلاثة أزرار اختيار في النموذج وكلها تحمل نفس الاسم ( animal ) ، فإن formEl.elements.animal ستعطي رابطًا لمجموعة من أزرار الاختيار (عنصر تحكم واحد ، 3 عناصر HTML). وإذا كنت تستخدم formEl.elements.animal.value للتصميم ، formEl.elements.animal.value قيمة زر الاختيار الذي formEl.elements.animal.value المستخدم.

إذا فكرت في الأمر ، فسيبدو الأمر غريبًا جدًا ، لذلك دعونا نتعامل مع المثال السابق:

  • formEl عنصر.
  • elements عبارة عن كائن HTMLFormControlsCollection يشبه صفيفًا لكنه ليس كذلك. عناصرها ليست بالضرورة عناصر HTML.
  • animal هو مجموعة من عدة أزرار راديو ، مقدمة كمجموعة بسبب حقيقة أن جميعها لها نفس سمة name (هناك واجهة RadioNodeList مصممة خصيصًا للعمل مع أزرار الراديو).
  • value استخدام value للوصول إلى سمة value لزر التحديد النشط في المجموعة.

رقم 15: حدد الطريقة ()


ربما في نهاية المادة ، سيكون من الأفضل التحدث عن طريقة مدهشة للغاية ، على الرغم من أن هذه الطريقة قد تكون وحيًا لشخص ما. لذا ، تتيح لك طريقة .select() تحديد النص في حقول الإدخال التي يتم استدعاؤها.

الملخص


في هذه المقالة ، تحدثنا عن طرق وخصائص غير معروفة يمكن استخدامها للعمل مع محتويات صفحات الويب. نأمل أن تكون قد وجدت هنا شيئًا جديدًا لنفسك ، وربما ليس جديدًا فحسب ، بل مفيدًا أيضًا.

أعزائي القراء! هل تستخدم أي وسيلة للتفاعل الآلي مع محتويات صفحات الويب غير المعروفة على نطاق واسع؟

Source: https://habr.com/ru/post/ar416539/


All Articles