ממשקי API של HTML

בהקדמה לסדרה הזו כתוב "רכיבי HTML הם הצמתים שמרכיבים את Document Object Model". דיברנו על סוגי צמתים של רכיבים. בקטע הזה נדון בממשקי API של רכיבים שמאפשרים לשלוח שאילתות לצמתים האלה.

DOM ו-AOM

DOM הוא ממשק API לגישה למסמכים ולשינוי שלהם. DOM הוא העץ של כל הצמתים במסמך. לחלק מהצומתים יכולים להיות צאצאים, ולחלק מהם לא. העץ כולל רכיבים, יחד עם המאפיינים שלהם וצמתים של טקסט.

עץ צמתים של MLW שמוצגים בו אלמנטים וצמתים של טקסט.

הכלים בדפדפן לא מספקים תצוגות חזותיות של עצים כמו זו שלמעלה, אבל אפשר לראות את הצמתים בבודק הרכיבים.

ה-DOM/ARIA.

ייצוג העץ שאפשר לבדוק בכלים למפתחים בדפדפן הוא עץ הנגישות. ה-AOM מבוסס על ה-DOM. באופן דומה, עץ הנגישות מכיל אובייקטים שמייצגים את כל רכיבי ה-Markup, המאפיינים וצמתי הטקסט:

דוגמה ל-AOM.

ממשקי API של רכיבי HTML

האות האמצעית של DOM היא 'object'. בדומה לדוגמה של האובייקט person או car שמופיעה ברוב הכיתות למתחילים בנושא תכנות מונחה-אובייקטים, כל צומת בעץ המסמך הוא אובייקט שאפשר לבצע בו פעולות באמצעות JavaScript.

הדפדפן מספק מספר רב של ממשקי API שמספקים שיטות, אירועים ושאילתות לנכסים שתומכים בהם באופן מקורי, וגם עדכונים של נכסים. צמתים של רכיבים מכילים מידע על כל המאפיינים שהוגדרו לרכיב. אפשר להשתמש בממשקי HTML כדי לגשת למידע על המאפיינים של רכיב. לדוגמה, אפשר להשתמש ב-HTMLImageElement.alt כדי לקבל את המאפיינים alt של כל התמונות:

let allImages = document.querySelectorAll('img');
allImages.forEach((imageInstance) => {
  console.log(imageInstance.alt);
});

ממשקי HTML מספקים יותר מגישה למאפיינים של רכיב. אפשר לגשת למידע הרבה יותר רחב. אנחנו יכולים למצוא את המאפיין HTMLElement.offsetHeight לקריאה בלבד כדי לקבל את הגובה של כל קטע בדף שלנו, ביחס לפריסה.

let allSections = document.querySelectorAll('section');
allSections.forEach((sectionInstance) => {
  console.log(sectionInstance.offsetHeight);
});

אם המשתמש ישנה את כיוון המכשיר או ישנה את רוחב שדה התצוגה בדרך אחרת, הגובה של כל <section> ישתנה ומאפייני ה-DOM יתעדכנו באופן אוטומטי בהתאם.

ממשקי ה-API של ממשק ה-HTML לא מוגבלים לגישה לערכים של מאפיינים. ה-DOM מספק תובנות לגבי המצב הנוכחי של ממשק המשתמש. לממשקי API של HTML יש גישה לכל המידע הזה. אפשר לגשת לאורך הסרטון, כשהצפייה נמצאת בהפעלה הנוכחית, וגם אם הסרטון (או האודיו) הפסיק לפעול באמצעות HTMLMediaElement.duration,‏ HTMLMediaElement.currentTime ו-HTMLMediaElement.ended, בהתאמה.

ממשקי האלמנטים הזמינים

רוב רכיבי ה-HTML שעסקנו בהם עד כה בסדרה הזו, וגם רכיבים שעוד נעסוק בהם, מלבד כמה רכיבי חלוקה, כוללים ממשק DOM משויך. ממשק הבסיס של כל הרכיבים נקרא Element (רכיב). הממשק HTMLElement עובר בירושה מ-Element, וכל הממשקים הספציפיים לאלמנטים של HTML עוברים בירושה ממנו. ממשקים ספציפיים לרכיבים מסוימים מיושמים באמצעות כמה רכיבים דומים.

הממשקים כוללים:

נוהל השמות הוא 'HTML' ואחריו אלמנט או קיבוץ של אלמנטים באותיות רישיות גדולות בסגנון 'camel case', ואחריו 'Element', אבל החלק של האלמנט או הקיבוץ של האלמנטים לא פועל לפי דפוס מדויק. אל דאגה. אין צורך לזכור אותם. חשוב רק לדעת שהם קיימים כדי שתוכלו לחפש אותם כשצריך.

אם יש לכם אוסף של רכיבים, יש גם ממשקי אוסף מסוימים. לדוגמה, השיטה HTMLCollection.namedItem() מחזירה את הרכיב הראשון באוסף שהמאפיין id או name שלו תואם לפרמטר, או null אם אין רכיב תואם.

ליותר מ-30 רכיבים אין ממשק DOM משויך מלבד HTMLElement, כולל <address>,‏ <article>, ‏ <section>, ‏ <nav>, ‏ <header>, ‏ <footer>, ‏ <aside> ו-<hgroup>. לאלמנטים רבים שלא תומכים במאפיינים לא גלובליים שלא הוצאו משימוש יש ממשקים ספציפיים לאלמנטים, כמו HTMLPElement (האלמנט <p>) ו-HTMLUnknownElement (<😃> או אלמנטים אחרים שלא מוגדרים), אבל הממשקים האלה לא מטמיעים שום מאפיינים או שיטות נוספים מעבר למאפיינים ולשיטות שעברו בירושה מ-HTMLElement, והם לא מופיעים ברשימה שלמעלה.

שיטות API ומאפיינים יתירים

אם לממשק יש שם זהה לזה של שיטת או מאפיין של ממשק שהוא עובר בירושה, השיטה או המאפיין שעוברים בירושה מחליפים את השיטה או המאפיין שעוברים בירושה. במילים אחרות, שיטות ומאפיינים של הורה מבטלים את השיטות והמאפיינים של הצאצאים. כשניגשנו למאפיינים alt ו-offsetHeight ב-HTML Element APIs באמצעות imageInstance.alt ו-sectionInstance.offsetHeight, בהתאמה, הקוד לא זיהה לאיזה ממשק API הייתה גישה. בדרך כלל, כמו בשתי הדוגמאות האלה, אין בכך בעיה.

עם זאת, יש מקרים שבהם יתירות עלולה לגרום לבעיה. לדוגמה, HTMLCollection.length הוא לקריאה בלבד, אבל לממשק היורש, HTMLOptionsCollection, יש מאפיין length (שחוזר רק על ידי המאפיין options של <select>) עם הרשאות קריאה וכתיבה. אפשר להשתמש ב-HTMLOptionsCollection כדי להגדיר את גודל האוסף.

ממשקים אחרים

יש ממשקים נוספים שמאפשרים לבצע מניפולציות במיקומי ההסתעפויות של צמתים ב-DOM. הממשק EventTarget, שמספק את addEventListener() ואת removeEventListener(), עובר בירושה לממשקים Node ו-Window. בתורו, הממשקים של Element,‏ Document ו-DocumentFragment (שציינו ברכיבים מותאמים אישית) יורשים מ-Node, והממשק של HTMLElement יורש מ-Element.

הממשק node

כל סוג של צומת DOM מיוצג על ידי ממשק שמבוסס על Node, שמספק מידע ושיטות כאשר רכיבים קשורים לעץ ה-DOM. הממשק Node מאפשר להריץ שאילתות ולהוסיף צמתים לעץ הצמתים.

הפונקציה המפורסמת של Douglas Crockford, 'walk the DOM', משתמשת במאפיינים firstChild ו-nextSibling של Node.

const walk_the_DOM = function walk(node, callback) {
  callback(node);
  node = node.firstChild;
  while (node) {
    walk(node, callback);
    node = node.nextSibling;
  }
};

השתמשנו בשיטות appendChild() ו-cloneNode() של Node כדי להגדיר רכיבים בהתאמה אישית. בממשק Node יש הרבה מאפיינים ושיטות שימושיים לשליחת שאילתות ל-DOM ולביצוע פעולות עליו.

customElements.define('star-rating',
  class extends HTMLElement {
    constructor() {
      super(); // Always call super first in constructor
      const starRating = document.getElementById('star-rating-template').content;
      const shadowRoot = this.