ראשי > dhtml חוצה דפדפנים > מאמר חלק 1 > יצירת עצמים חוצי דפדפנים

יצירת עצמים חוצי דפדפנים

 בגיליון אוגוסט של המגזין המקוון Netscape World (שכעת נקרא Netscape Enterprise Developer) פרסמתי מאמר , שעסק בתאימות בין הדפדפנים בנושא  DHTML וטכנולוגיות אינטרנט אחרות. ניתן לגשת אל המאמר דרך רשימת המקורות. שם דיברתי על המימוש הראשון שלי של עצמים חוצי דפדפנים, עצמי סקריפטים שמסתירים את פרטי המימוש של הדפדפן ממפתח האינטרנט.

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

הרחבתי את הרעיון בספר שכתבתי עבור ספרי IDG בנושא HTML דינמית  (“Power Guide to Dynamic HTML" בהוצאת ספרי IDG, ינואר 1998). בספר יצרתי עצמים מורכבים מסקריפטים שמחביאים את מימוש המיקום בנטסקייפ ובמיקרוסופט, ואז השתמשתי בעצמים אלה ליצירת אפליקציות מורכבות של DHTML.

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

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

העצמים חוצי הדפדפנים שיצרתי עבור WDVL נועדו ליצור שני סוגים שונים של אפליקציות שיוצרות "כרטיס אינדקס". אפליקציות אלה יציגו או יסתירו תוכן ויזיזו את התוכן בעמוד. תוך מעקב אחר העיקרון של שמירת הפשטות, וידיעת הדרישות, העצמים חוצי הדפדפנים של WDVL יכילו מצביעים לפונקציות שיראו, יסתירו או יזיזו את האלמנט ע"י קביעת ערכי top ו-left שלו. רציתי אפשרות לגשת לערכי top ו-left הנוכחיים של האלמנט, כדי ליצור תנועה יחסית במקום תנועה אבסולוטית של התוכן, ולשם כך יצרתי שיטות להשגת שני הערכים האלו.

לצורך יצירת העצמים, נדרשתי ליצור פונקציה שתשמש כפונקציה בנאית (constructor) עבור כל עצם. הפונקציה תיקח מצביע התייחסות (reference) לאלמנט HTML ותקצה את המצביע לתכונה ספציפית של העצם. הפונקציה גם תקבע סט של מצביעים לפונקציות שמתנהגות כשיטות (methods) של העצם. את השיטות עצמן ניצור מאוחר יותר במאמר. הקוד עבור עצם של נוויגטור הוא:

// create NS cross-browser object
function wdvlNewObject(obj) {
this.obj = obj;
// cannot assign object directly to "this"
this.objHide = objHide;
this.objShow = objShow;
this.objGetLeft = objGetLeft;
this.objGetTop = objGetTop;
this.objSetTop = objSetTop;
this.objSetLeft = objSetLeft;
}

הפונקציה תיקרא בשם wdvlNewObject, והיא תכיל את תכונות העצם כמו גם מצביע לעצם עצמו ומצביעים ל6- השיטות שעליהן דובר קודם. מדוע שיטות במקום תכונות? הקצאת ערך חדש לתכונה לא מפעילה את השינוי בעצם. השינוי בעצם מופעל רק כאשר התכונה בעצם היסודי משתנה, לא בעצם חוצה הדפדפן שלנו. בנוסף, עקבתי אחר ההמלצות של תכנות מונחה עצמים, שאומרות שכדאי לגשת לתכונות העצם דרך שיטות ולא דרך גישה ישירה לתכונות, מה שנקרא גם הסתרת מידע או encapsulation. בגישה זו, ניתן לבצע שינויים בעצם היסודי בלי שזה ישפיע על אפליקציות שמשתמשות בעצמים.

העצם ב-IE די דומה לעצם של נוויגטור, חוץ מהעובדה שנשמר מצביע לתכונה/עצם style, במקום מצביע לאובייקט עצמו:

// create IE DHTML equalizer object
function wdvlNewObject(obj) {
this.obj = obj.style;
this.name = obj.id;
this.objHide = objHide;
this.objShow = objShow;
this.objGetLeft = objGetLeft;
this.objGetTop = objGetTop;
this.objSetTop = objSetTop;
this.objSetLeft = objSetLeft;
}

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

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

// hide element
function objHide() {
this.obj.visibility = "hidden";
}
// show element
function objShow() {
this.obj.visibility = "inherit";
}
// element's left position
function objGetLeft() {
return this.obj.left;
}
// element's top position
function objGetTop () {
return this.obj.top;
}
// set element's top position
function objSetTop(top) {
this.obj.top = top;
}

// set element's left position
function objSetLeft(left) {
this.obj.left = left;
}

והשיטות עבור העצם של IE הן:

// hide element
function objHide() {
this.obj.visibility = "hidden";
}
// show element
function objShow() {
this.obj.visibility = "inherit";
}
// element's left position
function objGetLeft() {
return this.obj.pixelLeft;
}
// element's top position
function objGetTop () {
return this.obj.pixelTop;
}
// set element's top position
function objSetTop (top) {
this.obj.pixelTop = top;
}

// set element's left position
function objSetLeft(left) {
this.obj.pixelLeft = left;
}

הצעד האמיתי שיש לקחת ליצירת העצמים הוא ליצור שגרה שתעבור על עמוד האינטרנט ותמשוך את העצמים לתוך מערך. שגרה כזו נקראת במהלך אירוע onLoad של טעינת הדף, כדי לאתחל את העצמים חוצי הדפדפנים. שגרת האתחול עבור נוויגטור היא:  

// function to instantiate equalizer objects
function wdvlCreateObjects() {
   wdvlObjs = new Array(document.layers.length);
   for (i = 0; i < document.layers.length; i++)      
      // check to see if Netscape assigned block
      if (document.layers[i].id.substring(0,3) != "_js") 
      wdvlObjs[document.layers[i].id] =
    new wdvlNewObject(document.layers[i]);
}

הפונקציה משתמשת במערך layers, שבנוי מראש בנוויגטור, כדי לגשת לכל האלמנטים של הרבדים. אלמנט רובד הוא אלמנט שמוגדר ע"י שימוש בתג layer, או ממוקם תוך שימוש בגיליון סגנון CSS-P. אם משתמשים באלמנט רובד, הוא נקרא בשם ע"י שימוש בתכונה name. עבור בלוקים של DIV, האלמנט נקרא בשם ע"י שימוש ב-ID. במעבר על המערך, לקחתי רק את האלמנטים שנקראו בשם, כיוון שהעצמים חוצי הדפדפן של WDVL נגישים רק לפי שמם. נטסקייפ מעניקה שם ברירת מחדל לכל עצם שלא ניתן לו שם, והוא שם שמתחיל בתחילית “_js”. כך, בקוד האתחול בדקתי את 3 התווים הראשונים של השם כדי לראות אם הוא מתאים לתחילית, ואם לא, הכנסתי את העצם למערך העצמים.

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

פונקצית האתחול של IE מופיעה למטה. שלא כמו נוויגטור, מיקרוסופט מושכת את כל האלמנטים של HTML בעמוד לתוך אוסף שנקרא all. השגרה בוחרת מהאוסף רק את האלמנטים שנמצאו בבלוק DIV והם בעלי שמות:

// function to create named and unnamed objects
function wdvlCreateObjects() {
   theelements = document.all.tags("DIV");
   wdvlObjs = new Array();
   for (i = 0; i < theelements.length; i++){
      if (theelements[i].id != "") {
   wdvlObjs[theelements[i].id] =
   new wdvlNewObject(theelements[i]);
   }
      }
}

ברגע שנוצר הקוד עבור כל דפדפן, הוא נשמר בתוך הקובץ של קוד-המקור ב-JavaScript, ie4_obj.js עבור העצם של IE 4.0, ו-ns4_obj.js עבור העצם של נוויגטור 4.0. בהמשך נראה איך לשלב את העצמים האלה בעמוד האינטרנט.

לעמוד הקודם      לעמוד הראשי        לעמוד הבא