顯示具有 JavaScript 標籤的文章。 顯示所有文章
顯示具有 JavaScript 標籤的文章。 顯示所有文章

2009年12月19日 星期六

TiddlyWiki 中文存檔不會亂碼的方法

如果注意過 TiddlyWiki 的 HTML 檔案, 你會發現 Firefox 所儲存的中文是很直覺的內容,
tiddlywiki-chinese

但是 IE 或是 Google Chrome 所儲存的中文卻是『很難看得懂的編碼』(簡稱『亂碼』?)
tiddlywiki-html-entity

這是怎麼一回事, 有沒有辦法來改善呢?

.


(...繼續閱讀.../...CONTINUE...)

2009年4月23日 星期四

HSL 色彩空間的視覺效果

接下來的『相關度』和『標籤雲』都會加上 HSL 的方式來處理顏色。在改版發表之前, 可以到我的『HSL 測試頁』先體驗一下。

image 
一般的作法 線性內差 得到的『色彩漸層』中間的部分常常是 灰色
image
但是, 在 HSL 色彩空間 得到的卻是彩虹般的『紅橙黃綠藍』

.

HSL 色彩空間的注意事項

  • 設定的 minColor, maxColor 還是以 RGB 表示的
  • 直接從 .colorHSL = 0, 1, 2 選一個滿意的『視覺效果』就可以了

簡單吧 !! Image

.

.

好奇寶寶分隔線

是的, 使用者只需要以 RGB 來設定顏色, 程式內部會自動換算 RGB 到 HSL,

Image如果你還是好奇, 希望以下這些『應用面的觀念』可以幫助進一步了解 ……

  • HSL 和 RGB 色彩空間 (色座標) 有何不同?
  • HSL 和 RGB 色彩空間 為何會影響『視覺效果』?
  • HSL 色彩空間的其他細節

.

最後, 才是給程式設計者的參考資料:

  • HSL 的程式設計參考資料

.

HSL 和 RGB 色彩空間的不同

RGB 色彩空間

  • R : Red = 紅色
  • G : Green = 綠色
  • B : Blue = 藍色

image

類似『直角座標』的方式 

HSL 色彩空間

  • H : hue= 色相
  • S : saturation = 飽和度
  • L : lightness = 亮度

 image

類似『極座標』的方式

此外, 還有和 HSL 類似的 HSV (色相 hue, 飽和度 saturation, 明度 value), 詳情請看  :

096_K書

.

HSL 和 RGB 色彩空間的視覺效果

image 
一般的作法從 青色 RGB=#00FFFF 線性內差到 紅色 #FF0000, 得到的『色彩漸層』中間的部分是 灰色 #808080
image
但是, 在 HSL 色彩空間 得到的卻是彩虹般的『紅橙黃綠藍』

下面的圖示可以幫助理解,

  • 路徑 0 : 一般 RGB 的作法, 兩個顏色的內差路徑常常會經過中間灰色的部份

 

  • 路徑 1 : HSL 色彩空間, 使用角度來表示 hue (色相), 所以內差路徑會呈現『弧線』或 『螺旋線』, 而經過比較多的顏色
  • 路徑 2 : HSL 採用 極座標系統, 所以同樣兩個顏色之間的內差路徑可以有兩個方向

 

image 099_鞭

HSL 色彩空間, 使用角度來表示 hue (色相)

  • R : Red = 紅色 (0度)
  • G : Green = 綠色 (120度)
  • B : Blue = 藍色 (240度)
  • Y:Yellow = 黃色 (60度)
  • C:Cyan = 青色 /青綠色 (180度)
  • M:Magenta = 洋紅色 / 品紅色 (300度)

.

把對應的 RGB 變化也一起畫出來 (在 HSL 測試頁 可以自己輸入顏色)

image
0: 傳統 RGB 運算方式

(左圖)
在簡單的線性內差之下, RGB 一起變化, 產生的視覺效果並不理想


(下左, 下圖)
經過 HSL 的換算之後, RGB 依序變化, 就變得非常精彩 
image
1: HSL不跨過0度
image
2: HSL 經過0度 (紅/紫色)

.

HSL 色彩空間的其他細節

還有一些細節, 不見得每個人都會遇到, 下面先簡單帶過, 建議到我的『HSL 測試頁』去『實際體驗』一下, 會更有感覺, 或是隨時提出來討論

Image擔心被搞混的人, 就不一定要往下看囉~~

項目

測試參數

  • HSL 採用 極座標系統, 所以同樣兩個顏色之間的內差路徑可以有兩個方向, 目前的定義是
    • 1: HSL 內差路徑不跨過0度
    • 2: HSL 內差路徑經過0度 (紅/紫色)
    • 0: 傳統 RGB 運算方式

任意兩個顏色, 觀察 0, 1, 2 的不同
  • 紅色 (0度) 附近的 紅偏橙 #FFxx00 和 紅偏紫 #FF00xx, 可以產生出不一樣的效果
  • maxColor = (255, 1, 0) 或 (255, 0, 1), 搭配任意的 minColor
  • maxColor = (255, 1, 0), minColor = (255, 0, 1), 或對調
  • 非常接近的灰色 (或黑色), 可以因為 hue (色相) 的不同, 而有不同的效果
  • 任意顏色, 搭配 (33, 32, 32), (32, 33, 32), (32, 32, 33), (33, 33, 32) 或其他不同的灰/黑色

.

HSL 的程式設計參考資料

Image
之前在處理『相關度』和『標籤雲』的顏色時, 就在思考如何呈現出 更理想的『色彩漸層』

當時所使用的方法, 效果雖然還不錯, 但設定上比較麻煩, 也不容易理解。

所以, 除了 依相關度排序的『相關文章』功能 提到 optionRGB = […] 之外, 並沒有做太多的介紹。

這些程式, 都還沒有使用 HSL 色彩空間 來處理顏色

.

後來, 有機會和『標籤文章選台器』的作者 LVCHEN 討論到這方面的問題, 提到或許可以將 色座標改用 HSL (色調,飽和度,亮度), 又不約而同找到類似的 RGB <=> HSL 轉換程式 ……

現在, 在我的程式裡看到的是『改寫的 RGB <=> HSL 轉換函數』, 產生的 HSL 只適合程式內部使用。如果要用作其他用途, 建議還是參考下面的『原出處』:

.

另外, HSL 測試頁 還用到了 JavaScript Vectorgraphics Library 來繪圖

.


(...繼續閱讀.../...CONTINUE...)

2008年7月20日 星期日

To jQuery or Not To, 『非 jQuery 習作』- 隨機文章跑馬燈

暫且不討論用 jQuery 來寫程式到底好不好, 因為我大概也沒有足夠的 JavaScript 資歷來討論這件事。不過, 倒是把前一陣子的『 jQuery 習作 - 隨機文章跑馬燈』改寫成不用 jQuery 的方式, 以下和大家分享。

.

最近, 自己寫的『相關文章點播台』外掛和其他功能暫告一段落, 轉而開始注意我的 Blogger 部落格的載入速度, 除了將大部分 JavaScript 加了 defer="defer" 屬性 (IE7似乎有問題), 也拿掉一些少用的 外部 JavaScript, 詳情可以參考以下的說明 :

.

再來, 把前一陣子的『 jQuery 習作 - 隨機文章跑馬燈』改寫成不用 jQuery 的方式。雖然原先 jQuery 的方式沒什麼問題, 但有了 LVCHEN 的提醒, 總是多一分準備會好一些。

...試著不用 jQuery 寫,其實對於學習 js 的幫助也不小,而且 jQuery 其實也有些 bug,太過依賴反而不好,碰到 bug 反而會花上更多時間。

=> LVCHEN 回應 『 jQuery 習作 - 隨機文章跑馬燈 』

.

模版修改方式、其他說明 以及 限制, 請見『 jQuery 習作 - 隨機文章跑馬燈』, 下面只列出 放在 HTML/JavaScript 網頁元素裡的 JavaScript

變數類別 :

  • DOM 物件 : eArch
  • DOM 物件陣列 : aPost, aHref, aTemp
  • 字串 : sTemp

其他注意事項 :

  • 紅色部分, 要搭配模版的架構, 還有 跑馬燈 的命名
  • 藍色部分 : i<20 可以改成其他的文章篇數,
  • 藍色部分 : /*/> */ 是因為輸入 HTML/JavaScript 網頁元素時, < > 必需成對, 用 &lt; 又無效, 所以只好用 JavaScript 註解的方式補成 i<20; /*/> */
  • 整段程式也可以放在模版, 但是 藍色部分 要改成
    for (var i=0; i &lt; 20; i++)

jQuery 的方式

不使用 jQuery 的方式

(IE7 不適用, 最後面有另一版本)

<!-- 記得先載入 jQuery -->

<script type="text/javascript">
function myScroller() {
var shortspc = ' ';
var longspc = ' ';
var p_lnk = $('#BlogArchive1').find('.posts').find('a');
var ll = p_lnk.length;
var j = Math.floor((ll) * Math.random());
$('#U002').html('').append('[' + j + '/' + ll + ']' + longspc);
for (var i=0; i<20; /*/> */ i++){
j = j+1;
j = j % p_lnk.length;
var d0=p_lnk.eq(j).attr("href");
d0 = d0.match(/\d{4}\/\d{2}/);
$('#U002').append(d0+shortspc);
p_lnk.eq(j).clone().appendTo('#U002');
$('#U002').append(longspc);
};
}

$(document).ready(function(e){
myScroller()
});
</script>

<script type="text/javascript">
function myScroller() {
var shortspc = ' ';
var longspc = ' ';
var eArch = document.getElementById('BlogArchive1');
var aPost = eArch.getElementsByClassName('posts');
var aHref = [];
var aTemp = [];
var sTemp = '';
var i,j;
for (i=0; i</*/>*/ aPost.length; i++) {
aTemp = aPost[i].getElementsByTagName('a');
for (j=0; j</*/>*/ aTemp.length; j++) {
aHref.push(aTemp[j]);
}}
var ll = aHref.length;
j = Math.floor((ll) * Math.random());
sTemp = sTemp.concat('[' + j + '/' + ll + ']' + longspc);
for (var i=0; i<20; /*/> */ i++){
j = j+1;
j = j % ll;
var d0=aHref[j].href;
d0 = d0.match(/\d{4}\/\d{2}/);
sTemp = sTemp.concat(d0+shortspc);
sTemp = sTemp.concat(aHref[j].parentNode.innerHTML+longspc);
};
document.getElementById('U002').innerHTML=sTemp;
}
myScroller();
</script>

.

IE7 不適用 getElementsByClassName 改寫如下 (綠色部份) :

<script type="text/javascript">
function myScroller() {
var shortspc = ' ';
var longspc = ' ';
var eArch = document.getElementById('BlogArchive1');
var aTemp = eArch.getElementsByTagName('a');
var aHref = [];
var sTemp = '';
var i,j;
for (i=0; i</*>*/ aTemp.length; i++) {
if (aTemp[i].href.match(/\d{4}\/\d{2}/))
if (!aTemp[i].href.match(/Id=BlogArchive1/i))
{ aHref.push(aTemp[i]); }
}

var ll = aHref.length;
var j = Math.floor((ll) * Math.random());
sTemp = sTemp.concat('[' + j + '/' + ll + ']' + longspc);
for (var i=0; i<20; /*/> */ i++){
j = j+1;
j = j % ll;
var d0=aHref[j].href;
d0 = d0.match(/\d{4}\/\d{2}/);
sTemp = sTemp.concat(d0+shortspc);
sTemp = sTemp.concat(aHref[j].parentNode.innerHTML+longspc);
};
document.getElementById('U002').innerHTML=sTemp;
}
myScroller();
</script>


(...繼續閱讀.../...CONTINUE...)

2008年7月18日 星期五

JavaScript 壓縮 與 除錯版本維護

不但找到合用的 JavaScript 壓縮服務 (Javascript Compressor), 同時還發現它的『特異功能』解決了我的另一個煩惱 ---- 維護『除錯版本』和『上線版本』的一致性。

於是, 壓縮的時候 會順便從『除錯版本』裡『自動拿掉除錯指令』變成『上線版本』, 而不用分成兩個檔案。

.

先簡單介紹 JavaScript 壓縮 ---- (底下借用各家的說明)

... 先「壓縮」,經過「瘦身」以後放上網路,這樣檔案會變小,使用者下載讀取的速度也會變快。... JSMin,... Packer,以及很多 Javascript Library 愛用的 Javascript Compressor,這些都可以讓你自己外掛或自行撰寫的 Javascript 達到壓縮的效果(減少不必要的字元),檔案變小、程式碼變少自然載入就會變快,這樣也是一種優化的好辦法。

http://javascriptcompressor.com/,它把原本的程式碼轉換成跟天書一樣,而且還可以測試還原回來的效果。
在javascript的壓縮,會把註解和突排刪除,甚至把程式全部變為一行。但是,將程式全部變成一行,這個問題就大了。因為如果在程式中,沒有每個敘述很嚴謹的用分號(;)來結束的話,從多行變成一行之後,程式會出錯。

Javascript Compressor 壓縮, 某些情況下,壓縮率可以接近 zip 壓縮

不過使用上需要注意 JavaScript 的語法格式, 最常遇到問題就是斷行與分號

JSLint 幫你檢查未定義的變數、函數、陳述式結尾有沒有加分號(;)、變數使用之前要先用 var 宣告、使用非數字的變數要用 === 或 !== 讓比對的時候不要自動進行轉型(Casting)、盡量不要使用 eval 函數、... 好多好多,驗證完之後會立即出一份完整的報告給你。

.

再來, 是 Javascript Compressor 的『特異功能』, 只要在行首開頭加上三個分號 (;;;), 那一整行就會在壓縮時被當做註解一樣移除,

和註解不同的是, 這些指令在『除錯版本』會被執行, 但不會出現在『上線版本』, 於是壓縮的時候 會順便從『除錯版本』裡『自動拿掉除錯指令』變成『上線版本』, 而不用分成兩個檔案。

就像底下這樣, 兩個除錯函式 debugWrite, debugWriteIf, 和呼叫它們的部份都不會出現在壓縮過的『上線版本』裡

;;; rpsFunc.debugWrite = function(a) {
;;; rps$.msg.append('<li>' + a + '</li>');
;;; };

;;; rpsFunc.debugWriteIf = function(cond, a) {
;;; if (rpsDebug.mode.search(cond)>=0) {
;;; rps$.msg.append('<li>' + a + '</li>');
;;; }
;;; };

rpsFunc.redrawBoard = function () {
myHeadmsg = DispReplace(rpsDisp.ListHead);
;;; rps$.Board.find('#headmsg').text('').append(myQQ + myHeadmsg + '</span>'); // for debug
rps$.Board.find('#headmsg').text('').append(myHeadmsg); // for debug
rps$.Board.find('#progress').text('');
rps$.mainList.html('<ul>'); // mainList renew
...

.

至於『除錯版本』不執行, 但『上線版本』要執行的指令則可以這樣處理 :

  • if 搭配一個變數控制『除錯版本』要不要執行, 但 if 及對應的 { } 則不會出現在『上線版本』, 中間的指令就會被執行

  • 『除錯版本』的指令被夾在註解裡, 但『上線版本』則會執行這些指令

;;; if (!rpsDebug.jsonLocal) {
rpsFunc.readOK();
;;; }

...

;;; /*
rps$.Board.append('<br />');
;;; */

.


(...繼續閱讀.../...CONTINUE...)

2008年7月17日 星期四

相關文章點播台 -- RPS 1.0 beta 測試

前一陣子開始改良『依相關度排序的相關文章』, 現在已經進入beta 測試。

目前取的名字叫『相關文章點播台』-- RPS 1.0 (Related Posts Surf), 相較於 之前從 Abin's Tech Note 那邊修改過來的版本, 主要的不同為 :

  • 以外掛的形式執行, 完全不用改模版, 只要一行就可以安裝
  • 增加換頁功能
  • 增加自訂設定

.

  • 安裝

真的只要一行, 就像底下這樣, 只要在載入 jQuery 之後再執行就可以。程式會找到預設的位置顯示相關文章

<script src="http://eucaly61-java.googlecode.com/svn/trunk/rps-10-mini.js" type="text/javascript"/>

然後, 如果一切順利的話, 就會看到類似底下的畫面

 2008-07-17_214909

.

  • 基本設定

如果沒有順利顯示, 或是位置不如預期, 可以加入以下的參數 :

<script type="text/javascript">

rpsOpt.LocateBoard = ['append', '.post-footer'];
rpsOpt.LocateLabels = ['.post-footer', '.post-labels', 'a'];

</script>

如果你的部落格網址太特別, 或是你想『顯示另一個 Blogger 部落格的相關文章』 , 或是調整每一頁的文章篇數:

<script type="text/javascript">

rpsOpt.blogRoot = 'http://eucaly61.blogspot.com/';
rpsOpt.Lines = 10;

</script>

.

其中 'append', '.post-footer' 表示『顯示位置』的 CSS 設定,

  • 'append', 也可以改成 'prepend''after''before', ---- 和 '.post-footer' 的關係如下所示,
  • 第一個參數如果不是上述四個, 則會視為 CSS 位置表示語法, 並預設為 'append'
  • 再來是 CSS (Cascading Style Sheets) 位置表示語法, 簡單的說, 『.』句號代表 class, 『#』井號代表 id, 開頭都沒加代表 html tag,
  • 可以設定多個 CSS 位置表示語法, 會讓定位更精準, 記得都要加上引號
  • 目前預設『必須剛好』找到一個位置, 才會顯示, 這是為了區別『單篇文章』,『首頁』和『瀏覽日期/標籤』。

如果改為 rpsOpt.LocateBoard = ['.post-footer', '.post-footer-line-1']; 則會顯示在 [B] 的位置。

[before]
<div class='post-footer'>
[prepend]
<p class='post-footer-line post-footer-line-1'>
... 張貼者: XXXX 位於 ... </p> [B]
<p class='post-footer-line post-footer-line-2'> ... 標籤:... </p>
<p class='post-footer-line post-footer-line-3'>
... 這裡不一定每個人都有內容 ... </p>
[append]
</div>
[after]

.

如果上面對了, 至少會顯示『載入中』

2008-07-17_215300

再來是定位標籤資料, rpsOpt.LocateLabels = ['.post-footer', '.post-labels', 'a']; 如果你的模版和下面不一樣, 請自行修改

  • 如果你的『標籤名稱』不是用 <a href="..."> 超連結包住,
    .... 目前暫時無解, 請期待 下一版
<div class='post-footer'>
<p class='post-footer-line post-footer-line-1'>
... 張貼者: XXXX 位於 ... </p> <p class='post-footer-line post-footer-line-2'>
<span class="post-labels">標籤:
<a href="..." rel="tag">標籤名稱1</a>,... </p>
<a href="..." rel="tag">標籤名稱2</a>,... </p>
</span>

.

  • 進階設定

<script type="text/javascript">

rpsDisp.Loading = '相關文章載入中 ...';
rpsDisp.ListHead = '約有 %PostNum% 篇相關文章,以下是第 %PostNumFrom% 至 %PostNumTo% 篇';
rpsDisp.ListLine = '%PostRank% %PostTitle% - %PostDate%';

</script>

可以任意調換順序, 或者如果不想看到日期或相關度, 也可將 %PostRank% %PostDate% 等 拿掉。

<style>
#rpsBoard {
background: #F0F0F0;
border:2px dotted #ccc;
padding: 0px 5px 5px 15px;        /*上 右 下 左*/
margin: 10px 10px 5px 0px;        /*上 右 下 左*/
}
</style>

替相關文章區塊上色 ...., 或 padding, margin 請依版面自行調整。

.

  • 除錯

有問題的話, 可以試試以下的版本, 會有除錯訊息
[+/-] show/hide debug message

<script src="http://eucaly61-java.googlecode.com/svn/trunk/rps-10-debug.js" type="text/javascript"/>

<script type="text/javascript">

rpsDebug.mode = '%blog%label%jsOK%jsOK-full%';

</script>

.

  • To Do

可能的問題, 或預計增加的功能

  • 不同模版的相容性
  • 不同瀏覽器的相容性 (FF3, IE6, IE7, ...)
  • 載成更多 json Feed, 目前每個標籤只載入 20 篇
  • 調整 相關度計算方式
  • 顯示/隱藏文章摘要

想到但不一定會做的

  • 抓取同一網頁的其他資料, e.g. feedjit "Visitors to this page also liked"
  • 顯示每篇文章的標籤
  • 選擇哪些標籤的優先權較高

.


(...繼續閱讀.../...CONTINUE...)

2008年7月11日 星期五

用 jQuery 動態載入 json-in-script 的作法

在準備改版『依相關度排序的相關文章』的過程之中, 幾乎可以確定要用 jQuery 來寫, 不過其中有一個問題, 就是如何 動態載入 不同類別標籤 的 JSON, ....

好啦, 沒有打算要用 jQuery 來寫 json-in-script 的人, 請再忍耐一下, 看完下面這一句再轉台,

json-in-script 要當作 JavaScript 來載入, 所以用 jQuery 動態載入 json-in-script, 也就是要用 jQuery 動態載入 JavaScript 的意思。

今天終於讓我試出來了, 簡單的說, 要使用 jQuery 的 $.getScript() 或 $.ajax();

.

2008-07-17 : 請見意見的最新訊息, 或看底下是否有新的『相關文章』

原本, 靜態呼叫 json-in-script 的方式, 像底下這樣, 其中 VB 是類別標籤的名字, 問號 ( ? ) 後面的 alt=json-in-script&callback= ... , 則是設定回傳格式為 json-in-script, 以及指定 callback function

<script src="http://eucaly61.blogspot.com/feeds/posts/default/-/VB?alt=json-in-script&callback=RelatedLabels" type="text/javascript"/>

再來, 要注意的是 json-in-script 和 JSON 的差別,

  • JSON 指的是『資料格式』, 詳見 JSON Feeds (Beautiful Beta),
    也就是底下紅色的部分,
  • json-in-script 則是將 JSON 資料 回傳給 callback function,
    將 JSON 塞在括號內, 再呼叫 RelatedLabels()

不信的話, 點選上面 script src= 的 http:// 連結, 就會看到如下的內容,

RelatedLabels({"version":"1.0","encoding":"UTF-8","feed":{"xmlns":"http://www.w3.org/2005/Atom","xmlns$openSearch":"http://a9.com/-/spec/opensearchrss/1.0/","id":{"$t":"tag:blogger.com,1999:blog-8685080495061991394"},"updated":{"$t":"2008-07-10T22:12:07.563+08:00"},"title":{"type":"text","$t":"Beyond Alternative"},"link":[{"rel":"alternate","type":"text/html","href":http://eucaly61.blogspot.com/search/label/VB},
...
openSearch$totalResults":{"$t":"3"},"openSearch$startIndex":{"$t":"1"},"openSearch$itemsPerPage":{"$t":"25"},"entry":[{"id":{"$t":"tag:blogger.com,1999:blog-8685080495061991394.post-6282815987510613229"},"published":{"$t":"2008-06-27T23:23:00.001+08:00"},"updated":{"$t":"2008-06-28T00:29:03.151+08:00"},"category":[{"scheme":"http://www.blogger.com/atom/ns#","term":"程式設計"},{"scheme":"http://www.blogger.com/atom/ns#","term":"VB"},{"scheme":"http://www.blogger.com/atom/ns#","term":"Excel"}],"title":{"type":"text","$t":"[Excel 巨集] Address 函數 -- 傳回『範圍參照』"},"content":{"type":"html","$t":"\u003cp\u003e自從 2008-02 提出
... });

.

下面列出 jQuery 載入 JavaScript 的語法,
要記得, json-in-script 要當作 JavaScript 來載入

http://docs.jquery.com/Ajax

.

jQuery.getJSON( url, data, callback ) Returns: XMLHttpRequest

Load JSON data using an HTTP GET request.

jQuery.getScript( url, callback ) Returns: XMLHttpRequest

Loads, and executes, a local JavaScript file using an HTTP GET request.

.

下面是測試成功的程式,

function jsOK(a){
$('#msg').append('<p> END callback : ' + a + ' / ' + relatedPostsNum + '</p>');
for (var j=0; j < relatedPostsNum; j++) {
$('#msg').append('<p>' + relatedDates[j] + ' / ' + relatedTitles[j] + ' [' + relatedUrls[j] + '] </p>');
}
}

$(document).ready(function(){
$('body').prepend('<div id="msg"></div>');
$('#msg').append('<p> ready BEGIN </p>');
var feedUrl = "http://eucaly61.blogspot.com/feeds/posts/default/-/VB?alt=json-in-script&callback=RelatedLabels";

$.getScript(feedUrl, jsOK);
$('#msg').append('<p> ready END </p>');
});

其中

  • RelatedLabels 將 JSON 讀到陣列 (請參考上一篇),
    -- 根據實驗結果, 在這個函式中就算使用 jQuery, 也無法改變頁面內容

  • jsOK 則是在 json-in-script 執行成功之後 由 jQuery 呼叫,
    -- 根據實驗結果, 在這個函式中可以成功使用 jQuery 改變頁面內容

由此, 建議 callback 的 RelatedLabels 只要專心處理 json-in-script 的資料即可。至於頁面的資料顯示或其他需要 jQuery 的處理程序, 則留待 jsOK 再來處理

由執行結果得知, json-in-script (含 callback) 和 jsOK 會在背景執行 (非同步)。因為有遠端處理和回傳的延遲, 通常會到最後才出現結果, 而不會 夾在 "ready BEGIN" 和 "ready END" 之間。

ready BEGIN

ready END

END callback : undefined / 3

2008-06-27 / [Excel 巨集] Address 函數 -- 傳回『範圍參照』 [http://eucaly61.blogspot.com/2008/06/excel-vba-address-function.html]

2008-06-04 / 我的 Excel 日記 [http://eucaly61.blogspot.com/2008/06/my-excel-diary.html]

2008-02-20 / [程式設計構想] 使用 EXCEL 巨集合併/比對/更新多種格式的通訊錄 [http://eucaly61.blogspot.com/2008/02/excel-vb-to-managecombine-contact.html]

.

也可以使用比較低階的 $.ajax(), 它有 更多設定, 包括同步 (async: false), 非同步 (async: true) 等 ..., 不過目前試過 同步 (async: false) 並沒有看到預期的結果就是了。

$.ajax({
async: false,
type: "GET",
url: feedUrl,
dataType: "script",
success: jsOK
});

.

再來, 很奇怪的一件事, 如果使用下面這一行, 雖然成功傳值 'A' 給 jsOK, 但 json-in-script 卻沒有正確執行 (項目數為 0)

$.getScript(feedUrl, jsOK('A'));

ready BEGIN

END callback : A / 0

ready END

.

最後, 如果不想使用 jQuery, 那就用老方法, 例如 :

document.write, 但必需在 『網頁載入完畢之前』執行

document.write('<script src="..." type="text/javascript"/>');

或者

var s = document.createElement('script');
s.type = "text/javascript";
s.src = path;
var headobj = document.getElementsByTagName('head')[0];
headobj.appendChild(s);

.


(...繼續閱讀.../...CONTINUE...)

2008年7月10日 星期四

jQuery 習作 - 隨機文章跑馬燈

請看視窗底下的『隨機文章跑馬燈』, 這個算是我自己的 jQuery 習作, 不過也成功取代了載入速度不穩定的 ai-Ticker-J

.

  • 文章資料來源 (1)

一般的作法都是以 RSS Feed 提供『文章資料』, 寫在程式裡則以 JSON Feed 較方便。不過, 我要用不一樣的方法, 因為『文章資料』其實很多人的頁面都有 (就在某個網頁元素/widget 裡), 可以省去抓 Feed 的時間 (估計 0.5 ~ 2 秒)。

答案在更後面, 請耐心看下去。

.

  • 跑馬燈語法

跑馬燈語法 Scrolling Text - Marquee HTML Code (英文), 簡單的說, 就是包在 <marquee> ... </marquee> 裡面, 再加上 滑鼠移到上面時會暫停。其他的設定 (速度, 方向, ...) 該處也有說明。

<marquee onmouseover="this.stop()" onmouseout="this.start()">
要顯示的跑馬燈文字 </marquee>

.

  • 固定在視窗底下的語法

固定在視窗底下的語法, 沒有專文介紹, 但是在『挖哩勒~胡說八道』那裡, 找『頁面原始碼』的 #finalfooter2 就知道囉 -- (或者看後面, 我的程式碼 <span style=... 那一長串)

這是另外一個Hack喔,跟這個無關
因為有點複雜,所以我沒有寫
(最新文章跑馬燈, 挖哩勒~胡說八道)

.

  • jQuery 概念

可以先看 jQuery 教學 - 基礎篇 (wmh, jsGears)

我是 jQuery 新手, 所以只簡單列出曾在 LVCHEN 那裡看過的問題

... jQuery 必須先被執行,所以不管你放在哪裡一定要放在 jQuery 之後執行 ... (標籤文章選台器 1.2 版介紹與安裝, LVCHEN)

... 阿土伯的外掛是使用 jQuery 1.1.4,問題就發生在 jQuery 1.1.4 與 1.2 版以上是部份不相容的,如果同時安裝會導致留言開關不正常,... (最新回應 2.0 來囉!, LVCHEN)

... 記得jQuery 不要裝兩次 (加強型最新回應 for blogger ..., LVCHEN)

.

  • 文章資料來源 (2)

你答對了嗎?

.

2008-07-09_225128 

就是這個, 只要使用『階層式』的『網誌存檔 / BlogArchive', 文章資料就是現成的, ....


『階層式』『網誌存檔』的 HTML 原始碼  摘錄如下,
紅色部分 就是 jQuery 抓取資料的 HTML 標記, 還有我們需要的文章資料,
<div class="widget BlogArchive" id="BlogArchive1">
...
<a class="post-count-link" href="http://eucaly61.blogspot.com/2008_07_01_archive.html">七月</a>
<span class="post-count" dir="ltr">(2)</span>
<ul class="posts">
<li><a href="http://eucaly61.blogspot.com/2008/07/blog-post.html">[轉貼] 送愛心到泰北</a></li>
<li><a href="http://eucaly61.blogspot.com/2008/07/related-posts-with-correlation.html">依相關度排序 ---- 更有看頭的『相關文章』功能</a></li>
</ul>
...

不過, 雖然省掉了 JSON callback, 但還是有限制

  • 要使用『階層式』網誌存檔 / BlogArchive'
  • 只有『年, 月』, 而沒有『日』, 無法顯示文章的完整日期
  • 只會先載入較新的文章資訊 (約50篇), 除非 手動 或 自動 點開 摺疊的資料

.

當然, jQuery 也有自己的 方式來執行 JSON callback, 這部份留待日後再來嘗試, 有興趣的人可以參考 :

http://docs.jquery.com/Ajax

jQuery.getJSON( url, data, callback )    Returns: XMLHttpRequest

Load JSON data using an HTTP GET request.

jQuery.getScript( url, callback )    Returns: XMLHttpRequest

Loads, and executes, a local JavaScript file using an HTTP GET request.

.

  • 程式碼

先將底下的 HTML 加到 模版, 這麼做可以先『佔位置』, 讓 瀏覽器 讀入頁面時, 能正確排版。 至於位置其實沒那麼重要, 只要在 <body>...</body> 裡面即可, 例如 content-wrapper 之前。還有, 藍色部份的顏色, 請自行調整。

...
</div>
加在這裡
<div id='content-wrapper'>
...

<span style="position:fixed; border-top:1px solid #F0FFF0; border-bottom:1px solid #A8CEA8; background-color:#C0FFC0; width:100%; left:0; text-align:left; color:#000; font-size:12px; z-index:10000; opacity:0.8px; filter:alpha(opacity: 80); _position:absolute; bottom:0; _top:expression(document.body.scrollTop+document.body.clientHeight-this.clientHeight); padding-top:2px; padding-left:10px; padding-bottom:0; vertical-align:bottom; line-height:1.0; margin:0;">
<marquee id="U002" onmouseover="this.stop()" onmouseout="this.start()">
跑馬燈載入中 ... / Loading Marquee ...
</marquee> </span>

.

再將底下的 JavaScript 放到 HTML/JavaScript 網頁元素裡,

  • $() 是 jQuery() 的別名,
  • $(document).ready, 會在整個文章載入之後才執行, 所以網頁元素位置不是那麼重要, 只要在載入 jQuery 之後,
  • 紅色部分, 要搭配模版的架構, 還有 跑馬燈 的命名
  • 藍色部分 : i<20 可以改成其他的文章篇數,
  • 藍色部分 : /*/> */ 是因為輸入 HTML/JavaScript 網頁元素時, < > 必需成對, 用 &lt; 又無效, 所以只好用 JavaScript 註解的方式補成 i<20; /*/> */
  • 整段程式也可以放在模版, 但是 藍色部分 要改成
    for (var i=0; i &lt; 20; i++)

<!-- 記得先載入 jQuery -->

<script type="text/javascript">
function myScroller() {
  var shortspc = ' ';
  var longspc = ' ';
  var p_lnk = $('#BlogArchive1').find('.posts').find('a');
  var ll = p_lnk.length;
  var j = Math.floor((ll) * Math.random());
  $('#U002').html('').append('[' + j + '/' + ll + ']' + longspc);
for (var i=0; i<20; /*/> */ i++){
    j = j+1;
    j = j % p_lnk.length;
    var d0=p_lnk.eq(j).attr("href");
    d0 = d0.match(/\d{4}\/\d{2}/);
    $('#U002').append(d0+shortspc);
    p_lnk.eq(j).clone().appendTo('#U002');
    $('#U002').append(longspc);
  };
}

$(document).ready(function(e){
  myScroller()
});
</script>

.

其實也試過不修改模版, 而是將 綠色部分 也加在 程式中, 再用 $('body').prepend 的方式加上去, 但是只有 Firefox 可以正確顯示, IE7 則不行。

...
function myScroller() {
  var shortspc = ' ';
  var longspc = ' ';
  $('body')
  .prepend('<span style="..."><marquee id="U002" onmouseover="this.stop()" onmouseout="this.start()">
跑馬燈載入中 ... / Loading Marquee ... </marquee> </span>');
  var p_lnk = $('#BlogArchive1').find('.posts').find('a');
...

.

小結 -- 我的收穫

  • 寫了第一個 jQuery 程式
  • 不用再呼叫 ai-Ticker-J
  • 知道在 模版 和 網頁元素 要用不同方式處理 < >

.


(...繼續閱讀.../...CONTINUE...)

2008年7月9日 星期三

Blogger, JavaScript, JSON, jQuery 說明 及 教學 彙整

以下列出最近研究中的 Blogger, JavaScript, JSON, jQuery ... 的 說明 及 教學文件, 有需求的人可以從中參考。

.

Blogger 官方說明文件

Blogger Help > 自訂您的網誌 > 版面配置 > 瞭解更多資訊
Blogger Help > Customize Your Blog > Classic Templates > Advanced Use

.

Blogger 自訂/改造 教學

每一個出處都有許多 Blogger 自訂/改造 的相關文章, 以下僅列出『較具代表性』的, 其他造訪各站連結。

BLOGGER HACK (Abin's Tech Note)
經典的說明都從 Abin Tech Note 開始 ...

Blogger改造之旅 (白花花)
有人開路在先, 你也可以跟著改造你的 Blogger

部落格工具箱 (iPlay99)

Blogger (挖哩勒~胡說八道, 或使用該站右側欄的『文章選台器』)

.

JavaScript 教學

Java, JavaScript 說明文件

.

JSON Feed 說明文件

  • JSON Feeds (Beautiful Beta)
    ... 原來 JSON feeds 裡頭有每篇文章的標籤 ...
    json.feed.entry[i].category[j].term

.

jQuery 教學

jQuery 說明文件


http://docs.jquery.com/Core

- jQurey 說明文件
2008-07-09_093658

http://visualjquery.com/1.1.2.html
- jQuery 指令語法及範例 (階層式查詢)

2008-07-09_091550

.


(...繼續閱讀.../...CONTINUE...)

2008年7月2日 星期三

依相關度排序 ---- 更有看頭的『相關文章』功能

.

Correlation 前幾天, 成功實作出『Grazr格中格』的『相關文章』功能, 原本還要繼續嚐試 Google Ajax Search API 或 Google Ajax Feed API ...。不過, 最後還是決定回到『json 加 java script』, 再加上『依相關度排序』---- 希望可以就這麼定案 ----。

不過我猜, 說不定還得請大家投票來決定。

.

下面將介紹 :

  • 遺珠的『相關文章』功能
  • 原始版本的『相關文章』功能 -- Abin's Tech Note
  • 依相關度排序---- 讓『相關文章』更有看頭
  • 補充 ----『隨機文章』

另外寫了一個『不用寫程式, 不用改模版的方法』, 要先掛 jQuery, 再依文章所述安裝。目前的設計, 是要單篇文章才會顯示相關文章。對程式不熟的人, 建議使用 相關文章點播台 -- RPS 1.0 beta

有興趣『寫程式/改模版』的人, 再看下文。

.

  • 遺珠的『相關文章』功能

之所以沒使用下面這些, 來呈現『相關文章』, 有幾個原因 :

  • 無法呈現文章的相關性, 也無法處理重複文章
  • Google Ajax Search API 處理的是『關鍵字』, 而非『標籤』
  • 另外兩個某種程度上比較像『標籤文章選台器』, 而不是『相關文章』

.

不過, 還是列出它們的效果, 說不定你用得上。

Grazr-Related

『Grazr格中格』的『相關文章』功能

2008-07-01_140908
Google Ajax Feed API (Meme -- 教學與反省,
.阿欣部落.)

.

Ajax-Search
Google Ajax Search API

.

建議大家先看一下原始版本的『相關文章』做法 (加入相關文章功能, Abin's Tech Note 2007-03-05), 或者是 替Blogger加入相關文章功能(二)(挖哩勒~胡說八道, 2008-06-30)

裡面, 詳細介紹了『相關文章』的做法, 還有程式碼要安裝在模版的什麼地方。

簡單的說, ABIN 的做法如下 :

  • 集合A = 目前文章的標籤 * (每個標籤取出10 篇最新的文章, 並且不包含目前文章)
  • 集合B = 集合A 的 不重複文章
  • 相關文章 = 從 集合B 隨機取出 5 篇文章

.

  • 依相關度排序 ---- 讓『相關文章』更有看頭

再來看看我的做法, 不同之處以紅色標示 :

  • 集合A = 目前文章的標籤 * (每個標籤取出10 篇最新的文章, 並且不包含目前文章), 並記錄目前的文章有幾個標籤 (labelNum)
  • 集合B = 集合A 的 不重複文章, 並順便統計 每篇文章 在 集合A 出現的次數 (relatedStar),
  • 集合C = 將 集合B 依 文章次數 排序
  • 相關文章 = 集合C 依 文章次數, 由多到少列出, 相關度以 relatedStar / labelNum 表示

.

另外, 我還朝減少記憶體 (陣列) 使用量, 和減少迴圈次數的方向改寫, 所以直接就產生 集合B, 而且 集合C 也只是一個『索引』而已。這樣,『理論上』會跑快一點, 只是不知如何測試。

假設你已經安裝完成原始版本的『相關文章』([1][2]), 只要將 </head> 之前的程式碼整個換成我的版本, 就會有『依相關度排序』的效果。

.

其中的 optionRGB, 請改成適合的顏色設定

var optionRGB = [ {P: 100, R :208, G: 0, B: 0}, {P: 50, R: 255, G: 204, B: 0}, {P: 0, R: 0, G: 64, B: 128} ];

P = 百分比, (R, G, B) = 該百分比的顏色設定。如果介於兩個百分比之間, 則會使用中間色。也可以 增加 或 減少 顏色的組別, 但要維持 P (百分比) 由大到小排列, 還有注意語法即可。

P

R

G

B

100

208

0

0

50

255

204

0

0

0

64

128

.

如果不想使用顏色, 則將以下紅色部分刪去, 並注意 myRBG (內含 <span>) 和 </span> 是成對的。

myRBG = spanRGB(myP, optionRGB);
document.write('<h4>' + myRBG);
document.write('相關度 ' + myStars + ' ' + myP + '% 的文章 :</span></h4> <ul>' );

.

如果想用『分數』(例: 3/5 ) 來表示, 可以將灰色部份與前一行替換,

// document.write('相關度 ' + myStars + ' (' + relatedStar[r] + '/' + labelNum + ') 的文章 :</span> </h4> <ul>' );

.

再來是列出的文章總數, 目前是 20 則, 如藍色部分, 可以自行修改

for (var j=0; j<u_IdxNum && j<20 ; j++)

.

尚待努力之處

  • 看能不能再增進執行效率
  • 將程式主體搬到側邊欄, 縮短文章載入的時間, 之後再插入相關文章的結果

.

</head> 之前的程式碼如下 :

<script type='text/javascript'>
//<![CDATA[
<!-- Script functions for Related Posts: RelatedLabels(), RemoveDuplicatedPosts(), contains(), ShowRelatedPosts()-->
var relatedPostsNum = 0;
var labelNum = 0;
var maxStar = 1;
var relatedStar = new Array();
var relatedTitles = new Array();
var relatedUrls = new Array();
var relatedDates = new Array();
var u_Idx = new Array();
var u_IdxNum = 0;

function RelatedLabels(json) {
var regex1=/</g, regex2=/>/g;
var entryURL = "";
labelNum += 1;
for (var i = 0; i < json.feed.entry.length; i++) {
var entry = json.feed.entry[i];
entryURL = "";
for (var j = 0; j < entry.link.length; j++) {
if (entry.link[j].rel == 'alternate') {
entryURL = entry.link[j].href;
break;
}
}
if (entryURL != "") {
for (var j = 0; j <= relatedPostsNum; j++) {
if (relatedUrls[j] == entryURL) {
relatedStar[j]++;
if (relatedStar[j]>maxStar)
maxStar=relatedStar[j];
entryURL = "";
break;
}
}
}
if (entryURL != "") {
relatedPostsNum++;
relatedTitles[relatedPostsNum] = (entry.title.$t.replace(regex1, '&lt;')).replace(regex2, '&gt;');
relatedDates[relatedPostsNum] = entry.published.$t.substr(0,10);
relatedUrls[relatedPostsNum] = entryURL;
relatedStar[relatedPostsNum] = 1;
}
}
}

function SortRelatedPosts(PostUrl) {
for (var j = maxStar; j > 0 ; j--) {
for(var i = 0; i < relatedUrls.length; i++) {
if (relatedStar[i]==j && PostUrl != relatedUrls[i]) {
u_Idx[u_IdxNum] = i;
u_IdxNum++;
}
}
}
}

function spanRGB(myP, PRGB) {
var myR, myG, myB;
for (var i=0; i< PRGB.length; i++) {
if (myP >= PRGB[i].P) {
if (i==0) {
myR = PRGB[i].R;
myG = PRGB[i].G;
myB = PRGB[i].B;
} else {
var P0 = myP - PRGB[i].P;
var P1 = PRGB[i-1].P - myP;
var deltaP = PRGB[i-1].P - PRGB[i].P;
myR = Math.floor( (PRGB[i-1].R*P0 + PRGB[i].R*P1) / deltaP );
myG = Math.floor( (PRGB[i-1].G*P0 + PRGB[i].G*P1) / deltaP );
myB = Math.floor( (PRGB[i-1].B*P0 + PRGB[i].B*P1) / deltaP );
}
return('<span >');
break;
}
}
return('<span>');
}

function ShowRelatedPosts(PostUrl) {

var r = 0;
var i = 0;
var currStar = 0;
var myStars = "";
var myRBG;
var optionRGB = [ {P: 100, R :208, G: 0, B: 0}, {P: 50, R: 255, G: 204, B: 0}, {P: 0, R: 0, G: 64, B: 128} ];

SortRelatedPosts(PostUrl);
if (relatedTitles.length > 0) {
for (var j=0; j<u_IdxNum && j<20 ; j++) {
r = u_Idx[j];
if (currStar!=relatedStar[r]){
if (currStar != 0)
document.write('</ul>');
currStar = relatedStar[r];
myStars = "";
for (i=0; i<currStar; i++)
myStars = myStars + '★';
var myP = Math.floor(100*relatedStar[r]/labelNum);
myRBG = spanRGB(myP, optionRGB);
document.write('<h4>' + myRBG);
document.write('相關度 ' + myStars + ' ' + myP + '% 的文章 :</span></h4> <ul>' );
// document.write('相關度 ' + myStars + ' (' + relatedStar[r] + '/' + labelNum + ') 的文章 :</span> </h4> <ul>' );
}
document.write('<li><a href="' + relatedUrls[r] + '">' + relatedTitles[r] + '</a> - ' + relatedDates[r] + '</li>');
}
if (currStar != 0)
document.write('</ul>');
document.write('== 以上 ' + j + ' 則 ==, <a href="http://eucaly61.blogspot.com/2008/07/related-posts-with-correlation.html" target="_blank">相關文章及相關度說明</a>');
}
}
//]]>
</script>

.

另外寫了一個『不用寫程式, 不用改模版的方法』, 要先掛 jQuery, 再依文章所述安裝。對程式不熟的人, 建議使用 相關文章點播台 -- RPS 1.0 beta

.

  • 補充 ----『隨機文章』

至於『隨機文章』, 可以參考底下的做法, 將它的精神改寫到 ABIN 的程式裡面。

Blogger Feeling Lucky Widget (Random Post)

  • 按鈕呼叫 feelingLucky()
  • feelingLucky()

/feeds/posts/summary?max-results=0&alt=json-in-script 傳給 readLucky()

  • readLucky()

取得 文章總數, parseInt(feed.openSearch$totalResults.$t,10)
產生 亂數
將 亂數 傳給 fetchLuck()

  • fetchLuck()

/feeds/posts/summary?start-index=+亂數+&max-results=1&alt=json-in-script 傳給 showLucky()

  • showLucky

秀出文章

.


(...繼續閱讀.../...CONTINUE...)

2008年6月30日 星期一

『相關文章』『格中格』 -- Grazr

Grazr-Related

原本這一篇沒打算要獨立出來的, 但是上一篇似乎有點『落落長』, 而且那麼多程式碼也不見得每個人都有興趣, 所以就把需要程式碼較少的『相關文章格中格 -- Grazr'獨立成一篇,

至少, 在我試出更好的方法之前, 會在我的『單篇文章』之後, 看到如左圖的樣子, 好幾個 Grazr『格中格』疊在一起, 裝著不同標籤的相關文章, ...

.

請在模版加入下面的程式 (綠色部分), 我是全部加在 [B]

<p class='post-footer-line post-footer-line-2'>
<span class='post-labels'>
</p>
[A]
<p class='post-footer-line post-footer-line-3'/>
...
</div>
</div>
...
[B]
</b:includable>


找到適當地方, 放下面的程式,

[A] post-footer-line-2 整個段落之後, 如上圖, 會出現在 標籤 之後

[B] post-footer-line-3 之後的 </b:includable> 之前, 會出現在 FeedFlare 之後, 意見 之前

如果你的 標籤 意見 之間, 並沒有 Add to funPFeedFlare, 兩者的差別並不大

<b:if cond='data:blog.pageType == "item"'>
<b:if cond='data:post.labels'>
<p>相關文章</p>
<b:loop values='data:post.labels' var='label'>
<div> 相關文章 -- <b><data:label.name/></b></div>

<div style='height: 200px; width: 90%'>
<script defer='defer' expr:src='&quot;http://grazr.com/gzloader.js?file=http://eucaly61.blogspot.com/feeds/posts/full/-/&quot; + data:label.name + &quot;?alt=rss&amp;max-results=50&quot;' type='text/javascript'>
</script>
</div>

* 設定 高度 和 寬度, 可以用 絕對(px) 或 相對 (%)

* expr: 將 標籤名稱 (data:label.name) 傳給 Grazr




</b:loop>
</b:if>
</b:if>

.

就這樣, 再來就是調整字型和格式,

.

如果我試出更好的方法 (目標是 Google AJAX Feed API), 再請大家票選囉 !!

.


(...繼續閱讀.../...CONTINUE...)

『相關文章』-- 靈感啟發篇

雖然下面要介紹的『相關文章』功能, 我沒有直接使用, 但卻是很重要的起點, ....之前 (2007-11) 研究過一陣子『相關文章』的做法 (加入相關文章功能, Abin's Tech Note 2007-03-05), 雖然後來沒有直接採用, 但確實從中得到不少啟發。ABIN 的做法如下 :
  • 集合A = 目前文章的標籤 * (每個標籤取出10 篇最新的文章, 並且不包含目前文章)
  • 集合B = 集合A 的 不重複文章
  • 相關文章 = 從 集合B 隨機取出 5 篇文章
其中, 重要的概念有 :
  • http://網站名稱/feeds/posts/default/-/標籤名稱?alt=rss&max-results=傳回數量=> 代表包含特定標籤的 RSS, (default 也可以改為 full 或 summary), 請參考原文 (Blogger 資料來源用法與整理, ABIN)
  • 利用 expr: 來將 標籤名稱(data:label.name) 的 RSS 傳給『收集相關文章的函式』, 請參考原文 (加入相關文章功能, ABIN)
  • 利用模版中 顯示文章標籤的段落 來收集相關文章, 以下是原模版的內容 :
<span class='post-labels'> <b:if cond='data:post.labels'> <data:postLabelsLabel/> <b:loop values='data:post.labels' var='label'> <a expr:href='data:label.url' rel='tag'><data:label.name/></a> <b:if cond='data:label.isLast != &quot;true&quot;'>,</b:if> </b:loop> </b:if> </span> * 判斷文章是否有標籤 * 顯示『標籤:』 * 依次處理每一個標籤 * 顯示 標籤名稱(data:label.name)及 超連結('data:label.url' ) * 在標籤之間加上 逗號, 但最後一個標籤不加逗號
post-labels-1就像這個樣子!!..
  • 『相關文章』-- Google Ajax Search

用了好一陣子, 差不多把它當成『隨機文章』, 因為不知道該如何『餵』關鍵字給它, 所以只指定了『Eucaly61』, 看起來就像這樣 :Ajax-Search最近試出『餵』關鍵字的方法, 不過因為 Google AJAX Search API 的『Blog Bar』搜尋的是 RSS 裡的關鍵字, 所以如果 標籤名稱 沒有出現在本文裡, 還是不會被找到。(例如: 標籤名稱 是『程式設計』, 但文章本文卻不一定會出現『程式設計』...)雖然這樣, 還是分享一下程式碼, 說不定你用得上
<script type='text/javascript'> var myTotalLabel = new Array(); </script> </head> 把這幾行放在 </head> 之前, 這樣會定義一個空的全域變數
<p class='post-footer-line post-footer-line-2'> <span class='post-labels'> </p> [A] <p class='post-footer-line post-footer-line-3'/> ... </div> </div> ... [B] </b:includable> 再找到適當地方, 放下面的程式, [A] post-footer-line-2 整個段落之後, 如上圖, 會出現在 標籤 之後 [B] post-footer-line-3 之後的 </b:includable> 之前, 會出現在 FeedFlare 之後, 意見 之前 如果你的 標籤 意見 之間, 並沒有 Add to funPFeedFlare, 兩者的差別並不大
<b:if cond='data:blog.pageType == "item"'> <div id='blogBar-bar'> <span style='color:#676767;font-size:11px;margin:10px;padding:4px;'>Loading...</span> </div> </b:if> 我將這一段放在 [A] , 也可以選擇 [B] <b:if ...> 只有單篇文章會顯示 <div id='blogBar-bar'> ... </div> 讓 Google AJAX Search API 放置 BlogBar 的地方,
<b:if cond='data:blog.pageType == "item"'> <b:if cond='data:post.labels'> <b:loop values='data:post.labels' var='label'> <script type='text/javascript'> myTotalLabel.length += 1; myTotalLabel[myTotalLabel.length - 1] = &#39;<data:label.name/>&#39;; </script> </b:loop> <b:else/> <script type='text/javascript'> myTotalLabel.length += 1; myTotalLabel[myTotalLabel.length - 1] = &quot;Eucaly61&quot;; </script> </b:if> </b:if> 可以和 [A] 放在一起 或獨立放在 [B] 這邊是重點, 將 myTotalLabel 陣列擴充, 並一次加入一個 標籤名稱 沒有標籤時, 預設的內容
.再來是安裝 Google AJAX Search API, 請教 Google 大神就有一堆介紹了.找到你安裝 Google AJAX Search API 的地方, 重新指定 executeList,另外, 你可能也會想設定 largeResultSet, orderBy, siteRestriction 等參數, 或更多設定
autoExecuteList : { executeList : ["eucaly61"] } 原來的設定
autoExecuteList : { executeList : myTotalLabel } 重新指定 executeList
p.s. 或許 Use JavaScript Urls to drive the Blog Bar 也可以, 不過還沒試.
  • 下集預告

成功應用到『相關文章』的 Grazr『格中格』:計劃要使用的 Google AJAX Feed API :.

(...繼續閱讀.../...CONTINUE...)