2011年12月4日

Blogger 留言回覆系統自訂說明(回覆+引言+作者回覆+留言編號)

A+
2012.4.18 公告

由於 Blogger 推出新的串聯式留言,本文的 hack 只能使用在舊範本,而新範本有使用串聯式留言的話,請勿安裝本文的 hack。


無意間發現範本中留言區東改西改的結果,已經導致 sean大 的「作者回覆」功能在 IE 下失效(但其他瀏覽器是正常的)。於是乾脆自己另外想想作者回覆的功能怎麼寫,順便加強「插隊回覆」的功能及執行效率,並且將之前弄過的「回覆及引言按鈕」功能加以改進、統整進來,最後加上「留言編號」就成了完整的──留言回覆系統。

本篇為程式碼自訂說明,請看「上一篇」有簡易安裝說明及各種留言範例供使用參考。


二、完整 js 檔程式碼

  1. function WRCS(a,b,c,d){
  2.   if(a=="r"){reply_button(b,c)}
  3.   if(a=="q"){quote_button(b,c,d)}
  4.  
  5.   function reply_button(postID,commentID){
  6.     var url="https://www.blogger.com/comment.g?blogID=" + blogID + "&postID=" + postID + "&postBody=<" + commentID + ">("+escape("以上內容請勿刪除")+")#form"
  7.     window.open(url,"_blank")
  8.   }
  9.  
  10.   function quote_button(postID,commentID,body){
  11.     var url="https://www.blogger.com/comment.g?blogID=" + blogID + "&postID=" + postID + "&postBody=<" + commentID + ">("+escape("以上內容請勿刪除,以下引言請自行刪減")+")%20%20"+body+"#form"
  12.     window.open(url,"_blank")
  13.   }
  14.  
  15.   function NormalDiv(){
  16.     nComment.appendChild(dt)
  17.     nComment.appendChild(dd)
  18.     nComment.appendChild(ddf)
  19.     nComment.style.borderTop="#000060 1px dotted"
  20.     nComment.style.padding="5px"
  21.   }
  22.  
  23.   function OtherDiv(){
  24.     var sBr=document.createElement("br")
  25.     var s1=document.createElement("span")
  26.     var s2=document.createElement("span")
  27.     var sA=document.createElement("a")
  28.     var ReplyAuthor=document.getElementById("s1"+ReCID).title
  29.     var ReplyIndex=document.getElementById("s2"+ReCID).title
  30.  
  31.     if(ReplyIndex=="no"){
  32.       s1.innerHTML="回覆 "
  33.       s1.style.marginLeft="40px" 
  34.       sA.innerHTML="<b style='color:#416769'>"+ReplyAuthor+"</b>"
  35.       sA.href="#c"+ReCID
  36.       s2.innerText=" 的意見"
  37.     }
  38.     else {  
  39.       s1.innerHTML="回覆 <b style='color:#416769'>"+ReplyAuthor+"</b> 於 "
  40.       s1.style.marginLeft="40px"
  41.       sA.innerHTML="留言 #"+ReplyIndex
  42.       sA.href="#c"+ReCID
  43.       s2.innerText=" 的意見"
  44.     }
  45.   nComment.appendChild(dt)
  46.   nComment.appendChild(sBr)
  47.   nComment.appendChild(s1)
  48.   nComment.appendChild(sA)
  49.   nComment.appendChild(s2)
  50.   nComment.appendChild(dd)
  51.   nComment.appendChild(ddf)
  52.   nComment.style.borderTop="#000060 1px dotted"
  53.   nComment.style.padding="5px"
  54.   }
  55.  
  56.   var dl=document.getElementById("comments-block")
  57.   var dt=document.getElementById(dc_an)
  58.   var dd=document.getElementById(dc_bid)
  59.   var ddAll=dl.getElementsByTagName("dd")
  60.   var ddf
  61.  
  62.   for (var i=0; i<ddAll.length; i++){
  63.     if (ddAll[i].id==dc_bid){ddf=ddAll[i+1];break}
  64.   }
  65.  
  66.   var dta=dt.getElementsByTagName("a")
  67.   var ddp=dd.getElementsByTagName("p")
  68.   var cBody=ddp[0].innerHTML
  69.   var ReCID=""
  70.   var Author="no"
  71.   var ReplyHead=""
  72.  
  73.   if(cBody.search("&lt;")>=0 && cBody.search("&lt;")<20){
  74.     ReplyHead="yes"
  75.   }
  76.  
  77.   if(dta[1]){
  78.     if(dta[1].href.search(baURL)>0){Author="yes"}
  79.   }
  80.  
  81.   if(Author=="no" && typeof comment_index != "undefined"){
  82.     ++comment_index
  83.     var plus_zero
  84.     if (comment_index < 10){
  85.       plus_zero = "0" + comment_index
  86.     }
  87.     else {plus_zero = comment_index}
  88.     var aB=document.createElement("b")
  89.     aB.innerHTML="【留言 #"+plus_zero+"】"
  90.     aB.style.right="10px"
  91.     aB.style.position="absolute"
  92.     aB.style.font="12pt 標楷體"
  93.     aB.style.color="#003366"
  94.     dt.appendChild(aB)
  95.   }
  96.  
  97.   if(ReplyHead=="yes"){
  98.     var CIDstart=cBody.search("&lt;")
  99.     var CIDend=cBody.search("&gt;")
  100.     ReCID=cBody.substring(CIDstart+4,CIDend)
  101.   }
  102.  
  103.   var CIDstring="&lt;"+ReCID+"&gt;"
  104.   var ReplyText="(以上內容請勿刪除)"
  105.   var QuoteText="(以上內容請勿刪除,以下引言請自行刪減)"
  106.  
  107.   var qBody=cBody.replace(/\[quote\][\s\S]*?\[\/quote\]/g,"").replace(/<[^>]+>/g,"")
  108.   qBody=qBody.replace(CIDstring,"").replace(QuoteText,"").replace(ReplyText,"").replace(/\s/,"")
  109.   qBody=unescape(escape(qBody).replace(/%0A/g,"").replace(/%20/g,""))
  110.  
  111.   if (qBody.length>100){
  112.     qBody="[quote]"+qBody.substr(0,100)+"...[/quote]"
  113.   }
  114.   else {qBody="[quote]"+qBody+"[/quote]"}
  115.  
  116.   var s1CID="s1"+dc_id
  117.   var s2CID="s2"+dc_id
  118.   var s3CID="s3"+dc_id
  119.   var ci="no"
  120.  
  121.   if(typeof comment_index != "undefined"){
  122.     if(Author!="yes"){ 
  123.       ci=comment_index
  124.     }
  125.   }
  126.  
  127.   var reSpan=document.createElement("span")
  128.   reSpan.innerHTML="<span style='cursor: pointer; color: #3778cd;' onclick='WRCS(\"r\",\""+dp_id+"\",\""+dc_id+"\")'><回覆></span>∥<span style='cursor: pointer; color: #3778cd;' onclick='WRCS(\"q\",\""+dp_id+"\",\""+dc_id+"\",\""+escape(qBody)+"\")'><引言></span><span id='"+s1CID+"' title='"+dc_a+"'></span><span id='"+s2CID+"' title='"+ci+"'></span><span id='"+s3CID+"' title='"+Author+"'></span>"
  129.  
  130.   reSpan.style.right="10px"
  131.   reSpan.style.position="absolute"
  132.   ddf.appendChild(reSpan)
  133.  
  134.   if(navigator.userAgent.search("MSIE") > -1){
  135.     var nspan=document.createElement("span")
  136.     nspan.innerHTML=cBody.replace(/\[quote\]/ig,"<span name='ie'><b>引文:</b><br/><br/>").replace(/\[\/quote\]/ig,"</span>").replace(CIDstring,"").replace(QuoteText,"").replace(ReplyText,"")
  137.     ddp[0].innerHTML=nspan.innerHTML
  138.     var IE=ddp[0].getElementsByTagName("span")
  139.     for (var i=IE.length-1;i>-1;i--){
  140.       if(IE[i].name=="ie"){
  141.         var bq=document.createElement("blockquote")
  142.         bq.innerHTML=IE[i].innerHTML
  143.         bq.style.backgroundColor="#dddddd"
  144.         bq.style.border="#e69138 1px solid"
  145.         bq.style.padding="5px"
  146.         bq.style.wordWrap="break-word"
  147.         bq.style.wordBreak="break-all"
  148.         ddp[0].replaceChild(bq,IE[i])
  149.       }
  150.     }
  151.   }
  152.  
  153.   else {
  154.     ddp[0].innerHTML=ddp[0].innerHTML.replace(/\[quote\]/ig,"<blockquote style='background-color:#dddddd; border:#e69138 1px solid; padding:5px; word-wrap: break-word; word-break: break-all;'><b>引文:</b><br/><br/>").replace(/\[\/quote\]/ig,"</blockquote>").replace(CIDstring,"").replace(QuoteText,"").replace(ReplyText,"")
  155.   }
  156.  
  157.   var nDiv=document.createElement("div")
  158.   var nCID="n"+dc_id
  159.   nDiv.id=nCID
  160.   dl.insertBefore(nDiv,dt)
  161.   var nComment=document.getElementById(nCID)
  162.  
  163.   if(ReplyHead=="yes"){
  164.     if(Author=="yes"){
  165.       var rAuthor=document.getElementById("s3"+ReCID).title
  166.       var rdd=document.getElementById("dd"+ReCID)
  167.       if (rAuthor=="yes"){NormalDiv()}
  168.       else {
  169.         dl.insertBefore(nComment,rdd)
  170.         NormalDiv()  
  171.         nComment.style.backgroundColor="#e0eee0"
  172.         var np=document.createElement("p")
  173.         dl.insertBefore(np,rdd)
  174.       }
  175.     }
  176.     else {
  177.       OtherDiv()
  178.     }
  179.   }
  180.   else { 
  181.     NormalDiv()
  182.   }
  183. }
  184.  
  185. WRCS()



三、自訂留言編號

1. 如果已經裝過其他的留言編號 hack,那麼只要找出自己的留言編號程式碼,將留言編號變數改成跟本系統的變數 "comment_index" 一樣,最後刪除 CC~CQ 行即可。

2. 如果想變換留言編號的顏色、文字,那麼可以在 CC~CQ 行自行修改。

3. 如果留言編號想改放在自己喜歡的位置,那麼請將 CC~CQ 行刪除,然後參考「作者回應+留言編號」→「三、留言編號」,來另外安裝留言編號。

4. 修改 js 檔如用 word 開啟,需選 unicode 編碼,儲存時也是要選 unicode 編碼。


四、流程說明

以下說明 js 檔的執行過程,同時這也是跟各大瀏覽器奮戰後的結果,趕快做筆記留記錄以後才不會忘記,想要自訂細項配置的話請參考此節。

GC → A → BD ~ BL:Blogger 整個留言區是用 dl 標籤 包起來,每一則留言分別由「一個 dt、兩個 dd」標籤組成,本系統便是由這裡運用 javascript 的 DOM 概念下手,處理每則留言時只會針對「一個 dt、兩個 dd」標籤。請特別注意如果有動過留言區的程式碼,若留言區在「dl 與第一個 dt 標籤之間、第一個 dt 與第一個 dd 之間、或第一個 dd 與第二個 dd」之間有穿插其他的 HTML 標籤,那麼本系統不會處理到這些穿插的標籤,便可能造成您原本的 hack 失效,請自行看看怎麼把穿插的標遷移除、或是想辦法把穿插的標籤包到 dt 或 dd 標籤之內,這樣就比較不會有問題。

藉由 getElementById 定位的方式,BD~BL 行分別抓出「一個 dt 與兩個 dd」的位置。

BN → BY~CA:從 dt 裡面的第 2 個 a 標籤找出該篇留言是否為作者留言。(如果 dt 標籤有改過,請自行看看應該是第幾個 a 標籤才能判斷作者留言,請視情況修改dta[]括號裡面的數字)

BO~BP:留言內容就放在第一個 dd 的第一個 p 標籤內。(如果 dd 標籤有改過而不止一個 p 標籤,請視情況修改ddp[]括號裡面的數字)

BS → BV~BW:每則回覆會在開頭放 「&lt; 意見ID &gt;」這樣的字串以供系統判斷,因此找到「&lt;」這個字串就可確定這是回覆的留言。

CC~CQ:留言編號的程式碼,預設放在 dt 標籤最後面,顯示位置為固定在最右邊,只要判斷有找到 comment_index 這個變數、以及留言者不是作者,就印出留言編號。(使用 postion:absolute 因為 IE 在這裡不吃 float:righ;使用 innerHTML 因為 FireFox 這裡不吃 innerText)

CS~CW:如果之前檢查到該留言有意見 ID,在這裡取出意見 ID 放到 ReCID 變數。

CY~DE:把原留言的一些系統提示字串、意見 ID 字串、雜七雜八奇怪的符號、多餘標籤全部刪除。

DG~DJ:刪掉多餘字串後,如果原留言的字元還大於 100 個字元,只取前 100 個字元,接著在前後加上引言標記,將這些資料放在 qBody 這個變數,讓引言時可以取用。

DL~EB:動態做出一個 span 標籤,放在第二個 dd 標籤的尾巴,印出「回覆」及「引言」按鈕。同時藏三個看不見的 span 標籤,分別存放「留言者暱稱」、「留言編號」、「是否為作者」這三個資料,供之後方便取用。如果想改「回覆」及「引言」按鈕的位置,最好懂 DOM 文件結構,改 EB 行自己把這整個 span 標籤搬到別的區塊

ED~EU:令人生氣的一大段,由於 IE 下處理 innerHTML 的內容時,大部分標籤都不吃,尤其是最重要的 blockquote 標籤不吃,花了好長的時間繞了一大圈才做出 blockquote 的效果。

EW~EY:看看其他瀏覽器,簡簡單單一行就搞定了 把 [quote] 標記置換成 <blockquote> 這樣的動作,IE sucks... 想要改 blockquote 引言的底色、外框等等請在這幾行修改

FA~FE:處理完前面所有動作後,動態做出一個 div 區塊,擺放的位置用 insertBefore() 安插到 dt 標籤之前,之後準備把每則留言的 dt、兩個 dd 通通移到這個 div 區塊。在一開始有提過,本系統只處理「每則留言的 dt、兩個 dd 區塊」,所以如果有安插其他標籤、且這些標籤無法包到 dt、dd 裡面,那麼之後得自行把其他標籤給移到這個 div 區,才能顯現出這些其他標籤的效果。

FG~FS:這裡是作者回覆功能的關鍵,當留言搜尋到意見 ID 的字串、且是作者時,把「每則留言的 dt、兩個 dd 區塊」通通移到這個 div 區塊(命名為 nComment)。當初在範本安插的程式碼還包含了第三個 dd 區塊,此時發揮了重要的作用,把 nComment 這個 div 區塊用 insertBefore() 移到第三個 dd 區塊之前,這就成了「插隊回覆」的功能。因此當初想像中非常困難的插隊回覆功能,在實做上利用 DOM 概念時,反而是整個系統中比較簡單的一部份。

要自訂作者回覆區的顏色、樣式、配置請改這附近的程式碼,例如 FO 行可改底色,S 行可改作者回覆區的外框樣式(本系統預設每則留言只有上方有框線、框線樣式為虛線)。

FT~FU → W~BB:如果非作者回覆,那麼得做出跳到原留言的超連結。分成兩種情況:

AE~AK:如果使用者不用留言編號、或回覆的是作者,那麼超連結就不使用留言編號,超連結改用原留言者的暱稱。

AM~AR:如果需要使用留言編號的情況,將超連結改用留言編號。

想要變更回覆、超連結的文字可改以上 AE~AR 的區域

AS~BB:處理完超連結後,一樣把留言區內容全部塞到 nComment 這個 div 區塊,用 insertBefore() 移到第三個 dd 區塊之前。想設定非作者回覆的留言外框樣式、底色等等可在這個區域改

FX~FY:一般留言則執行這兩行。

還有兩個 function 沒有提到,就是開頭 E~H 行的「回覆按鈕」reply_button 函數以及 J~M 行的「引言按鈕」quote_button 函數,這裡能改的就是預設提示文字,請置換為自己喜歡的文字吧


五、修改 js 檔的提醒

1. 如有修改 js,網頁空間可參考「Google Code 簡易使用教學」;如果真的搞不定 google code 空間,那麼只好把修改過的 js 檔直接複製到範本中了,例如原本 js 檔的連結為這一行:

<script src='http://wayne-fu.googlecode.com/files/WRCS-share-20120418.js' type='text/javascript'/>
把這一行改為以下即可:

<script type='text/javascript'>
//<![CDATA[
修改過的 js 檔內容全部複製到此區間
//]]>
</script>

2. 重複一下,修改 js 檔如用 word 開啟,需選 unicode 編碼,儲存時也是要選 unicode 編碼,否則 js 檔可能會無法執行的。


六、最新回應模組修正

如果側邊欄小工具有安裝 Abin大 的「最新回應」模組,留言開頭會顯示冗長的意見 ID、系統預設字串、引言字串,如要刪除這些字串請參考這篇文章「最新回應模組修改」的文末增補進行修改。

沒有留言:

↑TOP

張貼留言注意事項:

◎ 勾選「通知我」可收到後續回覆的mail!
提問請附網址、詳細描述狀況,如提供的資訊不足,則無法回覆。
◎ 請在相關文章留言,與文章無關的主題請至「Blogger 中文論壇」。
◎ 若詢問 CSS 、非官方範本問題、或貴站為商業網站 ,請參考「本站諮詢頁面」→「1. 諮詢服務」
◎ 若留言要輸入語法,"<"、">"這兩個符號請用其他符號代替,否則語法會消失!
◎ 若發現留言不見了,通常是因為 "複製貼上" 的內容常被系統判定為垃圾留言,請不用擔心,我會定期將留言恢復。
◎ 本站「已關閉自刪留言功能」。