程式碼高𠅙

2008/04/21

用 JavaScript 來修飾你的超連結

網頁之間的互相引用、評論,是當代網誌的形式之一,而造就的結果就是正文之中充斥著超連結。

這樣的書寫風格本身並沒有所謂的好或不好。在我的日誌中,也存在不少此類用法。問題是,如果同一篇日誌中,重複提及一個特定的網頁,而該網頁又值得透過超連結參引,那麼重複編製超連結的動作,也會令人覺得繁瑣。

為此,我想到設定一種 "形式",再加上 JavaScript,來為正文中的特定字眼加上連結。

構想是,在每篇網誌的最後,加上一段 "相關連結" 或 "參考資料",段落名稱是什麼不重要,重點是:

  1. 將連結以無序清單的形式標明,每一清單項目以連結開頭
  2. 以冒號+空白 (": ") 來區分連結及解說文字,例如:
    • 愛頌過生活: 就是過日子,人生不需太多大道理!
    • DOM: Document Object Model (DOM); W3C 的官方說明

上例中的 "愛頌過生活" 及 "DOM" 字串,會被當作匹配條件,在正文的段落 (<p>...</p> 包起來的部分) 中,比對相符的字眼。若出現相符的字串,將被 JavaScript 套上超連結。

用來轉換文字成超連結的 JavaScript 程式碼如下:

<script type="text/javascript">
var init = {
  cmds: [],
  run: function(){
    for(i = 0; i < this.cmds.length; i++)
      this.cmds[i]();
  }
}

function getText(anchor){
   return anchor.text ? anchor.text : anchor.innerText;
}

function fixPostElements(){
   var uls = document.getElementsByTagName("ul");
   for(var i = 0; i < uls.length; i++)
      insertResourceLink(uls[i].parentNode)
}
function insertResourceLink(element) {
  var links= {};
  var lis = element.getElementsByTagName("li");
  for (var i = 0; i < lis.length; i++){
    if(lis[i].innerHTML.indexOf(": ") != 0){
      as = lis[i].getElementsByTagName("a");
      for(j = 0; j < as.length; j++)
        links[getText(as[j])] = as[j].href;
    }
  }
  var ps = element.getElementsByTagName("p");
  for(key in links) {
    var regKey = new RegExp(key, "g");
    for(var i = 0; i < ps.length; i++) {
      ps[i].innerHTML = ps[i].innerHTML.replace(regKey,
         "<a href="+ links[key] +">" + key +"</a>");
    }
  }
}
init.cmds.push(fixPostElements);
</script>

將上面的程式碼置於 HTML 的 head 區塊,在 body tag 中加上 onload="init.run()",於撰寫網誌時採用本文規範的形式,即可達所述的效果。

一篇符合本文形式規範的網誌文章,可參考 "PRISM for Firefox 3 beta 5 url link opening issue"。事實上,筆者正是在撰寫該文時,因對重複的超連結編製深感不耐,才產生此構想的。

附帶一提,如果讀者採用 Google Reader 或其他 RSS 閱讀軟體,那麼你將無法看到此 JavaScript 的效果,因為 RSS feed 中並不含 JavaScript 轉譯碼… 這樣的設計,或許可以解釋為:「為親自造訪本站的讀者,所提供的一點加值服務 ^__^」。

1 則留言:

sam 提到...

真是實用的功能啊!

大感謝!