OhBehave – החלת התנהגות על אלמנט סטטי או דינמי בצורה מיידית
באפליקציות ווב ואתרים עשירים, לעיתים קרובות יש צורך בהחלת התנהגות כלשהי על אלמנט.
דוגמאות:
- הפיכת תיבת select לפקד autocomplete
- השמת אלמנט בתוך מסגרת מורכבת (פינות מעוגלות, שקיפות)
- החלת אירועי לחיצה על אלמנטים מסוג מסויים
- השמת תווית צפה מעל פקד טקסט עד ל-focus/שינוי ערכו
פיתרון סטנדרטי יהיה להמתין לעליית ה-dom (פונקציה אשר מצוייה בכל ספריית js אשר מכבדת את עצמה), לרוץ על אלמנטים עם class מסויים, ולהפעיל פונקציית js שתחיל את ההתנהגות.
שימו לב! במידה ומדובר בהצמדת אירועים בלבד כדאי מאוד להשתמש בשיטת ה-Event Delegation
חסרונות השיטה:
- לפעמים, לוקח מעט זמן עד שה-dom עולה והאלמנט מופיע בגרסתו נטולת ההתנהגות עד לסיום הטעינה
- כאשר מוסיפים דינמית אלמנטים לעמוד (innerHTML או createElement & appendChild) צריך לדאוג להחיל את ההתנהגות שוב, על כל האלמנטים שדורשים זאת
- כפיתרון גנרי לאלמנטים דינמיים אפשר להפעיל טיימר על העמוד שיחקור את ה-dom בכל פעם מחדש. זהו תהליך איטי, וב-delay בקריאות ל-interval עלולות להיות קפיצות
דוגמה לעבודה בשיטה זו:
<script type=”text/javascript”>
function applyBehaviors() {
var elements=$.select(“.behavior”);
for (var i=0;i<elements.length;i++) applySpecificBehavior(elements[i]);
}
$.domready(function () {
applyBehaviors();
});
$.ajax("url.html",
onSuccess:function () {
applyBehaviors();
}
);
</script>
(הפונקציות $.select, $.domready, $.ajax הינן פונקציות פיקטיביות המקנות אפשרות לבחור אלמנטים לפי css selector, לבצע פעולה מייד בעליית ה-dom וביצוע בקשת ajax, בהתאמה. ניתן למצוא אותן בכל ספריית javascript המכבדת את עצמה).
הפיתרון הנכסף – OhBehave
OhBehave הינו סקריפט חביב, שאחראי על החלת התנהגות על אלמנטים באופן מיידי, ברגע הראשון בו הם זמינים. מבלי להמתין לטעינת שאר העמוד. בנוסף, מחיל את ההתנהגות גם על אלמנטים חדשים הנוצרים דינמית.
איך זה עובד?
לכל דפדפן נאלצתי למצוא פיתרון שונה, מאחר וכל אחד מיישם את הפונקציונליות בה רציתי באופן אחר. מתוך כל מנגנון בחרתי להפעיל פונקציה בשם OhBehave.initialize שמקבלת אלמנט ותניע את החלת ההתנהגויות.
התנהגויות האלמנט מוגדרות אף הן ב-class שלו. לדוגמה – oh-behave-WrapWithFrame, oh-behave-Autocomplete (שימו לב לקידומת oh-behave-).
כל התנהגות היא פונקציה המאוחסנת באובייקט OhBehave.behaviors שמקבלת אלמנט עליו היא מחילה התנהגות בודדת.
לא רציתי לכבול לשימוש ב-OhBehave, כך שניתן להגדיר את הפונקציה גם כגלובאלית, ואף ניתן לשנות את קידומת ההתנהגות (ראו בקובץ המצורף).
דוגמה:
OhBehave.behaviors["AlertTheTime"]=function (element) {
element.onclick=function () {
alert(new Date());
};
};
// or -- function AlertTheTime(element) { … }
Firefox (Gecko Engine) – שימוש ב-XBL
XBL או XML Binding Language היא שפת תגיות מבוססת XML המוגדרת בתקן W3C להחלת התנהגות עשירה לאלמנט. ה-XBL מאפשר להגדיר מאפיינים (כולל getters/setters), אירועים וירייתם, מתודות וקוד CSS/JS שיחול על האלמנט. ה-XBL מוצמד בעזרת css בתצורה:
.oh-behave { -moz-binding:url("oh-behave.xml#oh-behave"); }
ומבנה ה-xml:
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:html="http://www.w3.org/1999/xhtml">
<binding id="oh-behave">
<implementation>
<constructor>OhBehave.initialize(this);</constructor>
</implementation>
</binding>
</bindings>
כרגע רק מנוע Gecko תומך ב-XBL, על אף שהוא בתקן.
הצמדתי XBL ל-css class מסויים ומתוכו הפעלתי קוד גנרי המחיל התנהגות.
IE (Trident Engine) – שימוש ב-HTC
HTC, או HTML Component הינו יישום של Microsoft להחלת התנהגות עשירה לאלמנט. הוא מאפשר פחות או יותר את מה שה-XBL מאפשר.
Safari/Chrome (WebKit Engine) – האירוע DOMNodeInserted
מאחר וב-WebKit עוד לא הכניסו את XBL לשימוש (בקוד המקור יש אזכורים אך כנראה האופציה עדיין כבוייה), נאלצתי למצוא פיתרון אחר. האירוע DOMNodeInserted (אירוע המוגדר בתקן) נורה כאשר אלמנט מוכנס לעמוד דינמית (innerHTML / createElement & appendChild). דרך אירוע זה אני מחפש את האלמנטים עליהם יש להחיל את ההתנהגות. חיפוש האלמנטים מתבצע בעזרת querySelectorAll – מתודה של אלמנט או מסמך, המקבלת css selector ומגישה את כל האלמנטים העונים על סלקטור זה, תחת אותו אלמנט.
בעליית העמוד השתמשתי באירוע DOMContentLoaded שרץ מייד בעליית ה-dom. כאן עלולה להיות קפיצה קטנה, אבל המנוע כל-כך מהיר שאני לא חושב שיהיה אפשר להבחין בה.
דוגמה חיה
בעמוד הדוגמה ניתן לראות החלת שתי התנהגויות על אלמנט: הראשונה מקיפה אותו במסגרת הכוללת אלמנטים נוספים המרכיבים אותה, השניה מצמידה אירוע לחיצה המציג את הזמן הנוכחי.
בנוסף, כפתור אשר יוצר מוסיף אלמנטים חדשים למסמך בצורה דינמית, וגם עליהם חלות ההתנהגויות, Automagically.