קישורים ב-XHTML: פתיחת קישור בחלון חדש

‏ • 19 באפריל, 2005

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

באותה מידה W3C הכניסו לתקן מאפיין נוסף הנקרא rel שנמצא בתגי קישורים (a) ותגיות "הקשריות" כמו link. בהקשר של קישורים המאפיין הזה קובע את הקשר בין העמוד ל-target של הלינק. קשרים אפשריים הם: next, previous, chapter, section, ויש עוד. כמו כן W3C מאשרים הכנסת ערכים שלא מופיעים בתקן כערך למאפיין rel.
כיוון שלא קיים ערך המקיים את ה-target של עמוד חדש, עלינו להמציא אותו. לצורך המאמר נשתמש בערך external כדי לאפיין קשר זה. הערך external הוא מעין מוסכמה, אבל אפשר להשתמש באיזה ערך שרוצים עבור איפיון קשר זה (נכון לעת כתיבת המאמר). אם כך נראה הקישור בהתחלה:

<a href="https://www.webmaster.org.il" target="_blank"> https://www.webmaster.org.il </a> אז כך הקישור יראה לאחר השינוי:
<a href="https://www.webmaster.org.il" rel="external"> https://www.webmaster.org.il </a> הדפדפן לא יודע איך להתנהג עם הקשר הזה לכן הוא משתמש באופציית ברירת המחדל, לפתוח את העמוד באותו חלון. לכן עלינו לכתוב קוד ב-JavaScript שיפתח חלון חדש ברגע לחיצה על הקישור, ויבטל את האירוע של לחיצת הקישור כדי שהקישור לא יתבצע גם באותו חלון.

כדי לבצע את ההתאמה לדפדפנים (IE ודפדפנים תומכי תקן) אני משתמש במחלקה שאוריקס פירסם בוואב-אפדייט מס' 3

כדי לבצע את הנאמר יש מס' אפשרויות:


  • לתפוס את אירוע הלחיצה הגלובלי של המסמך ;

  • לעבור על כל הלינקים בדף ולתת להם אירוע Onclick יפתח עמוד חדש

אנחנו נתמקד באפשרות הראשונה. אלגוריתם הפעולה:
 – תפיסת אירוע הלחיצה הגלובלי של המסמך
  — לקיחת האלמנט שעליו התבצעה הפעולה
  — בדיקה שהאלמנט הוא קישור ושיש לו את המאפיין ref עם הערך external
  — אם כן:
    — פתיחת חלון חדש עם הלינק של הקישור
    — ביטול אירוע הלחיצה
  — סגירת הבדיקה
 – סגירת הטיפול באירוע

אם נתרגם זאת לקוד כך הוא יראה:

eventHandler.addEvent(document,
 "onclick",
 function(e){
  e = e?e:event;
  var target = eventHandler.getSrcElement(e);
  if(target && target.nodeName.toLowerCase()=="a" && target.getAttribute("rel")=="external"){
   open(target.href, target.title);
   // cancel event
  }
 }
);


אם תשימו לב יש שורת הערה שכתוב בה "// cancel event". אין בה פקודה כיוון שהדפדפנים עובדים אחרת עבור טיפול ביטול האירוע.
IE משתמש במאפיין returnValue עם הערך false כדי לבטל את הפעולה
דפדפני תומכי תקן (כמו פיירפוקס) עובדים עם השיטה preventDfault() כדי לבטל את הפעולה.
שני האפשרויות מגיעות דרך אובייקט האירוע. לכן הגיוני יהיה להרחיב את המחלקה לטיפול באירועים כך שיהיה בה גם שיטה לביטול האירוע:

eventHandler.cancelEvent = function(e){
  if(eventHandler.iBrowser===1){
    e.returnValue = false;
  }else{
    e.preventDefault();
  }
}

את השורה של ההערה נחליף ב:

eventHandler.cancelEvent(e); ולכן הקוד יראה כך:

eventHandler.addEvent(document,
  "onclick",
  function(e){
    e = e?e:event;
    var target = eventHandler.getSrcElement(e);
    if(target && target.nodeName.toLowerCase()=="a" && target.getAttribute("rel")=="external"){
      open(target.href, target.title);
      eventHandler.cancelEvent(e);
    }
  }
);
האפשרות השנייה היא דומה לאפשרות הראשונה אך במקום לתפוס את אירוע הלחיצה הגלובלי של המסמך, אנחנו עוברים בלולאה על כל הקישורים בעמוד ולכל קישור שיש מאפיין rel עם הערך external אנחנו מוסיפים את האירוע הלחיצה הכולל שתי פעולות: פתיחת הקישור בחלון חדש וביטול אירוע הלחיצה.
הקוד יראה כך:

eventHandler.addEvent(window,
 "onload",
 function(e){
  var anchors = document.body.getElementsByTagName("a");
  for(var i=0;i<anchors.length;i++){
    var a = anchors[i];
    if(a.getAttribute("rel")=="external"){
      eventHandler.addEvent(a, "onclick", function(ex){
        var target = eventHandler.getSrcElement(ex); open(target.href, target.title);
        eventHandler.cancelEvent(ex);
      }
    }
  }
 }
);

הסבר:
כדי להגיע לכל הקישורים הקיימים בדף צריך שקודם כל הדף יטען ולכן אנחנו עוטפים את הקוד בתוך אירוע onload, לאחר מכן קולטים את כל הקישורים הנמצאים ב-body של המסמך ועוברים עליהם בלולאה. בלולאה בודקים האם לקישור יש מאפיין rel עם הערך external במידה ויש מוסיפים לו אירוע לחיצה הפותח בחלון חדש את הקישור ומבטל את אירוע הלחיצה כדי שהקישור לא יפתח גם באותו מסמך.

תגיות: , , ,

ניר טייב

בונה אתרים ומתכנת בשפות:HTML, CSS, JavaScript, PHP 5, JSP&Servlets ורובי.

תגובות בפייסבוק