2006-11-13

首頁長篇文章的收合

當內文太長或圖片多的時候,進到首頁不但會變慢,版面也會拉很長,所以很多人的 Blog 首頁都會加上「繼續閱讀」、「閱讀全文」的連結,並且在首頁的新文章都只顯示部分內容,有興趣的再深入閱讀下去。好處就是剛剛講的,首頁如果能夠顯示十篇文章,頁面就不會因此要往下拉拉到死,也不會塞爆圖片慢得要死。

網路上看到兩種處理的辦法,一種是進首頁的時候還是全部都 Load,只是用收合折疊的方式讓首頁不要太長精簡一點,另外一種是只 Load 部分顯示出來,要閱讀全文就請你連到該文章的固定靜態連結。前者的好處是在首頁點開可以一目了然,但是圖多還是一樣很慢,後者的好處是載入很快,但是要跳轉到下一頁去看該篇文章,算是各有利弊。如果該長篇內容都是文字,我比較想用第一種,但如果有很多照片,第二種就比較好。我利用兩個標籤去實作了這兩種方法(算前無古人吧),隨便想用哪一種,只要指定不同的 ID 就好。

首先,登入 Blogger 管理介面,編輯範本 Template 的 HTML(要勾選"展開小裝置範本"="Expand Widget Templates",用最完整的原始碼),先到最前面定義 CSS Style 的地方去,隨便哪裡都可以,貼入以下基本的定義:

/* Style of detail article toggle */
span.showDetail {
  float: right;
  border: 1px solid #333;
  font-size: 8pt;
  margin: 10px 0 10px 0;
  padding: 0 10px 0 10px;
}

span.hideDetail {
  display: none;
  float: right;
  border: 1px solid #333;
  font-size: 8pt;
  margin: 10px 0 10px 0;
  padding: 0 10px 0 10px; 
}

其中那兩個 <span> 用的 class "showDetail", "hideDetail" 是用來定義那個收合文章用的連結樣式,自己可以新增對該連結的設定。因為有文章收合的效果,需要用到 Javascript,我用 inline 的方式插入 template 裡面,可是要注意,script code 裡面的判斷符號像是 '<' 或是 '&' 要轉換,不然 template 格式檢查會失敗。這裡提供一個技巧,在自己電腦上測試 template 時,可以另存新檔,附檔名取 .xml,然後用瀏覽器打開,瀏覽器會幫你檢驗 template (XML) 的格式有沒有問題,如果有錯在第幾行,這樣可以幫助你 debug。找範本的 </head> 標籤,把下面幾行 javascript 貼到該標籤的前面:

<!-- User defined inline javascript -->
<script language='javascript' type='text/javascript'>
<!-- Script functions for show detail article checking: showDetail(), hideDetail(), checkDetail() -->
function showDetail(id) {
  var spans = document.getElementById(id).getElementsByTagName('span');
  for (var i = 0; i &lt; spans.length; i++) {
    if (spans[i].id == 'detail' || spans[i].id == 'hideDetail')
      spans[i].style.display = 'inline';
    if (spans[i].id == 'showDetail')
      spans[i].style.display = 'none';
  }
}

function hideDetail(id) {
  var post = document.getElementById(id);
  var spans = post.getElementsByTagName('span');
  for (var i = 0; i &lt; spans.length; i++) {
    if (spans[i].id == 'detail' || spans[i].id == 'hideDetail')
      spans[i].style.display = 'none';
    if (spans[i].id == 'showDetail')
      spans[i].style.display = 'inline';
  }
  post.scrollIntoView(true);     
}

function checkDetail(id, link) {
  var spans = document.getElementById(id).getElementsByTagName('span');
  for (var i = 0; i &lt; spans.length; i++) {
    if (spans[i].id == 'detail') {
      spans[i].style.display = 'none';
      document.write('&lt;span id=showDetail class=showDetail&gt;');
      document.write('&lt;a onclick=javascript:showDetail(\&quot;'+id+'\&quot;); href=javascript:void(0);&gt;完整閱讀...&lt;/a&gt;');
      document.write('&lt;/span&gt;');
      document.write('&lt;span id=hideDetail class=hideDetail&gt;');
      document.write('&lt;a onclick=javascript:hideDetail(\&quot;'+id+'\&quot;); href=javascript:void(0);&gt;文章收合...&lt;/a&gt;');
      document.write('&lt;/span&gt;');
    }
    else {
      if (spans[i].id == 'fullpost') {
        spans[i].style.display = 'none';
        document.write('&lt;span id=showDetail class=showDetail&gt;');
        document.write('&lt;a href=\"'+link+'\"&gt;閱讀全文...&lt;/a&gt;');
        document.write('&lt;/span&gt;');
      }
    }
  }
}
</script>

接下來,搜尋下面這一行的程式:

<div class='post-header-line-1'/>

把上面那行後面幾行,本來應該是這樣的程式碼:(位置和版面會因樣版不同而有所差異)

<div class='post-body'>
      <p><data:post.body/></p>
<div style='clear: both;'/> <!-- clear for photos floats -->

改成這樣(變動的地方標註成紅色):

<div class='post-body' expr:id='"post-" + data:post.id'> <!-- Add show detail check -->
<b:if cond='data:blog.pageType == "item"'>
      <p><data:post.body/></p>
<b:else/>
      <style>#detail, #fullpost {display:none;}</style>
      <p><data:post.body/></p>
      <script type='text/javascript'>
        checkDetail(&quot;post-&quot; + &quot;<data:post.id/>&quot;, &quot;<data:post.url/>&quot;);
      </script>
</b:if>
<div style='clear: both;'/> <!-- clear for photos floats -->

樣版存檔,搞定!這個是版面樣式的 Template,接著我們到 Settings -> Formatting 最下面編輯文章發表用的 Post Template,加入下面一行:

<span id="detail"></span>

以後每次要發表新文章的時候,只要被 span 標籤像這樣包圍起來:

<span id="detail">
這是要隱藏剩下的完整內文
</span>

標籤內的文字就會在首頁被隱藏起來,而標籤外(不管是前面或後面)的文字就變成該文章的前言或摘要。以上是只有在首頁才會有的效果,如果是單篇獨立文章的連結,不會有展開折疊的連結,至於在 RSS Feed 裡面,因為大部分的 Feed Reader 都會濾掉格式的標籤,所以全部的內文也還是看得到。如果你不想使用文章收合的效果,要用固定連結,只要把上面的 id 名稱從 detail 改成 fullpost,就可以有獨立文章連結的效果了。

參考文章:
讓首頁文章可開啟/摺疊 for Blogger Beta
Expandable posts with Peekaboo view
有關 Blogger in Beta

[更新]:
1. 增加 ID: "fullpost",整合了網路上兩種「閱讀全文」的作法,如果 span 裡面指定成這個 ID,則連結前往該篇完整文章,不使用展開收合的效果。
2. 修正如果瀏覽器 script 功能關掉,看不到全文的問題(如果不支援 Javascript,則文章不隱藏,直接秀全文出來)。

回應: 40

Abin 提到...

已知的問題:在 IE 裡,首頁被收合的內文裡面的圖片,"可能"會看不見,code 語法一點錯都沒有,只能怪瀏覽器太爛,因為在 Firefox 裡一切正常。

Maggieblack 提到...

你好,謝謝你對圖片凸出的解答.
另外.請問一下,因為我想用圖片取代中文字.可是我把語言轉成%lt;img border='0' src='http://subwoofe.googlepages.com/evolve.gif' style='float:right;'/>
卻沒辦法顯示出來,請問是不是哪邊寫錯了>"< 3Q

Abin 提到...

要注意你這段程式是塞在哪裡,它是塞在 document.write(' '); 的裡面,所以你的 HTML 語法,絕對絕對不能用單引號 ' ',不然這個 document.write 的函示就破功了。
你要做的修改很簡單,把單引號改成雙引號就行了,像是這樣:
<img border="0" src="http://subwoofe.googlepages.com/evolve.gif"/>

Davin Chao 提到...

Abin大大:
我照您的方式修改了我的Blog。
但現在出現一個問題是,如果我按下其中一個lable的文章,我的"最新文章"相對應中會顯現所有該lable的文章,但當我點選其中一篇時,在左側的文章主體中,只有該文章的發表日期及標題有同步更新,文章主體的部分卻還是我首頁上原先最新文章主體。
不知我是否有哪個部分有遺漏掉?
還請您賜教。

iPlay99 提到...

哈囉~abin前輩您好~

我想請問一下,原本我是以
span class=fullpost來做繼續閱讀的

這樣子 javascript 裡要如何修改呢?

我改了 function checkDetail裡的幾個 寫 id 及 detail 的地方,沒半個矇到,只好來請教。

謝謝回答。

匿名 提到...

哈囉~abin前輩,我是sam,不用麻煩您了~後來決定把 class 捨棄掉~花了一點時間已經整理好了 :)

Abin 提到...

To Sam:
把 detail 關鍵字改成 fullpost,只要調換 function checkDetail 裡第三行和第十三行的順序就可以了,不能去多改到別的。

JHuei Ruan 提到...

哈囉~你好,感謝你提供的方法阿!

不過我套用了這方法之後,所有的東西都自動往左邊靠耶!(用firefox),不過在IE看都正常,應該是說原本是隨著視窗大小置中對齊,但是現在變成靠左邊對齊,可以請問一下是發生蝦米事情嗎....

JHuei Ruan 提到...

喔嗚!太蠢了我!搞了一個晚上,還好最後終於發現問題了!

我把css程式碼...貼到住解裏面去了= =+ 有夠蠢@@

KEEP 提到...

作者已經移除這則留言。

地獄的粉圓豆花 提到...

定義 CSS Style 的地方

↑是指那裡阿?

我是新手我找不到

可以跟我說一下去那裡找或怎麼找嗎?

Abin 提到...

To 地獄的粉圓豆花:
定義 CSS Style 的地方 -> 指的是在標籤<style>和</style>中間的區段。

匿名 提到...

請問這樣使用display:none會否被Google搜尋引擎懲罰? (隱藏式文字與連結 )

Abin 提到...

To Tim:
您的問題問得很好,我個人認為是不會。首先,這個 Hack 的原理是,在「首頁」模式,我才把幾萹文章部份的區段之後透過 span 設成 none,由於我的首頁會只顯示最新的幾篇文章,原則上我也不希望 Google 去 cache 我的首頁(因為首頁的內容會一直更新沒有時效性)。不過,我文章內文完整的模式,有永久固定的全文網址、完整顯示時 span 的狀態也是 inline,這部份不與 Google 的原則衝突。
大部分的 Blog 都是用這種模式來顯示文章(首頁只顯示部份、內文才完整),如果這樣會有懲罰,那大部分的 Blog 都進不了搜尋引擎的 cache 裡了。

Anson 提到...

請問我的文章有的會成功有的會失敗呢?本來用您這方法之前,我是用網路上找的方法加入小工具 "EasyReadMore" ,不過我覺都每次進 BLOG 還是有讀取大量圖片,所以改用您的方法
但是只有一篇有成功,其他偏都失敗。我後來看文章裡面有很多的 [/span] 標籤,不知道是不是這個原因導致程式不知道哪裡到哪裡該隱藏

請問我該怎麼解決這問題呢?

Anson 提到...

你好,關於先前問的問題,我自己找到解答了。原來是我自己寫作時一直自定文字的格式以及文字大小所造成。

另外一點請問您
用您的方式把文章收合,好像也會在背景讀取,是嗎?
因為我用 fire fox 3 瀏覽器,有掛流量的套件。套件在開啟我自己網頁時,有顯示大量的下載。但這同時我並無下載活動在進行

還請您幫我解答一下

Abin 提到...

To Anson:
這個 Hack 基本上和個人自訂樣板使用有很大關係,所以上面留言有很多人用起來會怪怪的,都是受自己版面設定和樣式的影響。
此外,從程式碼來看,運作原理是先讀完程式、再把該區段的 Display 設成 none,所以,也許你在版面沒看到那部份文章,但是背地裡還是都會載入讀完。因為 Blogger 本身並不支援類似「摘要」的功能,所以在文章載入時只會有全文,這個 hack 主要是調整版面、讓畫面顯示不要拉那麼長,並沒有辦法要首頁不去載入那個區段。

Hudson Gao 提到...

abin您好,我套用這個文章收合的hack有一段時間了,不過有個小問題,不曉得是不是只有我有這樣的狀況。

我在編輯文章的時候如果有在文字編輯器與html之間切換編輯,或是有在編輯器中使用ctrl+c / ctrl+v複製、增加顏色等,再切換到html看的話就會出現一堆的span、span id="fullpost"、/span這類標籤,最後文章寫好放到版面上,文末就會出現大概十幾個「完整閱讀」,也不能正常運作。這個問題讓我有點困擾,因為我得完全用html編輯。我的部落格又是以圖片為主,不曉得該怎麼辦..

又,我有看到上面有人留言說是因為他有自己設定字型,不過我的字型是統一以css定義的,所以文章除了粗體、顏色等幾乎不會在編輯時變到,但情況依舊,所以想請教abin這該如何解決,謝謝!

Abin 提到...

To Hudson:
抱歉,如果你習慣不用 HTML 來編輯文章,那我建議你不要在 Post Template 裡加入預設的 Span 標籤。
我也碰過你的狀況,因為直覺的文章編輯器,在複製貼上的時候,會自動幫你把要剪貼內容的 HTML 樣式一併複製,在貼上的時候「原始碼」內自動補進其樣式,如果你在 Post Template 裡放入 Span 標籤,因為有人也會拿 Span 做文字樣式的調整,所以你的編輯器也會一併紀錄和複製,加上 Blogger 內附的「樣式規則檢查」機制,又會自動檢查是不是有 Span 標籤沒完整的(又幫你補上結尾標籤),來回剪貼幾次,你的內文原始碼內就會多出一堆 Span 標籤,所以會有你看到的現象。
目前 Blogger 要做文章收合只能用手動嵌入程式碼的 HACK 方式做到,所以一定要切到程式碼調整,我建議你那在那個 Post Template 裡不要放進 Span 那段,等你反覆編輯、文章確定要發表公布前,才切到原始碼模式、找出你要收合那段用 Span 括起來,才能避免在非 HTML 模式、樣式被複製又被 Blogger 的檢查給調整造成的現象。

Hudson Gao 提到...

非常感謝abin的回答,經過幾天的試驗看來真的奏效了!再次感激您!

Sophia 提到...

Style of detail article toggle 與 User defined inline javascript 若勾選"展開小裝置範本"=",google出現執行錯誤
若不勾選則能存檔…所以想請教abin這該如何解決,謝謝!

Abin 提到...

To Sophia:
你提到的那兩句都只是「註解」,如果出現 Google 執行錯誤,應該是你程式碼貼錯位置了。你可以參考我網頁的原始碼,參考我程式碼放的位置。

Sophia 提到...

作者已經移除這則留言。

Sophia 提到...

我只打第一行文字
像把
User defined inline javascript
...

我僅貼這段javascript 貼到/head前,按儲存就出現錯誤…

Sophia 提到...

Abin您好,我用xx.xml從browser看,有段出現如下錯誤,可否請教這是什麼問題?謝謝。

名稱不可以使用多個冒號。處理資源 'file:///C:/Users/Sophia/Desktop/template-15448543128521040861.xml' 發生錯誤。第 856 行, 位置 23

Abin 提到...

To Sophia:
我剛剛有親自測試過,不管有沒有"展開小裝置範本",我在我樣板程式碼 </head> 標籤前貼入下面這一行:
<!-- User defined inline javascript -->
不管怎樣都不會有錯誤,我說過了,這一行僅是註解,而且是標準的 HTML 註解,如果你懷疑是這一行有問題,你大可以直接拿掉這一行。
我大概看了你現在 Blog 的原始碼,發現你用的 Hack 也不少,也有可能是其他程式碼在你剪貼的時候有衝突。另外,你貼出 xml 的錯誤給我看並沒有用,那是協助你自己 debug 的(我又看不到檔案內容,你期待我看到"名稱不可以使用多個冒號"就可以知道問題嗎?),這樣只能確定你的樣板程式碼的確有問題,請根據行號和位置自行 trace。

Sophia 提到...

Abin您好,我不是懷疑註解那行有問題,而是那整段貼下去有問題,那行註解只是代表性的開頭,我再試著debug,謝謝。

Abin 提到...

To Sophia:
我剛剛想到有一種可能,就是程式碼裡面的引號和保留符號導致檢查不能通過,我建議你可以在 script 標籤的前後各多加一行 meta 資料的宣告(粗體的那兩行、在程式碼內前後),例如:
<script type='text/javascript'>
//<![CDATA[
....... 這裡是剩下的程式碼
//]]>
</script>
看看這樣能不能解決你的問題。

Sophia 提到...

Abin您好,我把使用 HTML/JavaScript 的外掛程式拿掉,ex.CBOX,就能成功將長篇文章收合,謝謝你哦!!。

K i m i 提到...

實在是太感謝您的分享了!!!!
我現在的blog參考你提供的語法修改後完全就是我想要的樣子!!!
開心極了!!!
謝謝你!!!

nov2 提到...

Abin你好,很感謝你的教學,讓我成功的改善首頁loading太久的問題
但是我有個小問題,(我是新手,已經很努力學著看懂網頁語法)
我想將"繼續閱讀"這幾個字改成Read more,這個沒有問題,我做到了
我想將"Read more"將現行的右邊對齊想改成左邊對齊
不知道該怎麼處理,可否請你教教我
非常謝謝

Abin 提到...

To nov2:
float: right; 這句話是要求樣式靠右,你可以把 right 改成 left,或是直接刪掉這一行,就會預設靠左了。

nov2 提到...

Abin你好,非常謝謝你,依照你的指示,我已經成功的將字改成靠左對齊。
但也發現一件事情,
雖然首頁開啟(應該出現在首頁的所有文章段落都出現了)時間變短了,
但是似乎網頁並沒有loading完成,
左下角(我是用Mac、firefox瀏覽器)狀態列的地方,
持續出現有"從lh3.ggpht.com接收資料"(數字從3-6不斷變換)直到完全loading完成
這樣是發生什麼事了呢?
非常感謝你

Abin 提到...

To nov2:
本文有兩種收合文章的標籤,從程式碼來看,只要你開啟首頁,不管畫面上有沒有顯示圖片,它都會把資料讀完,因此即使你看畫面都出來了,但背景還是會乖乖把東西都 Load 完才會停止。尤其是使用 detail 這個能即時收合的標籤,雖然你沒看見,它還是要把所有文字甚至圖片都 Load 完,實際載入時間不會比較減少,但因為隱藏顯示,會讓讀者覺得每個區塊都出現了,但其實還在背景載入。
你看到接收資料的網址,是 Picasa、Google 的網路相簿,也是 Blogger 放置 Blog 圖片的地方,相信你的 Blog 應該有不少上傳的照片吧!建議你可以用 fullpost 的標籤,雖然要跳轉新頁面來閱讀全文,但可以減少首頁載入每篇文章所有照片要花的時間。

阿凜 提到...

站長你好,想請教您
如果想要關掉只顯示標題(內文被收合),恢復為會顯示標題與內文,要怎麼做呢><
因為我是用網路上別人分享的版型去修改,在首頁的確是標題內文都有顯示,但一旦用站內搜尋或標籤找文章,就只有標題,文章跟摘要都被自動收合
http://www.fileden.com/files/2006/11/30/441807/template-8379842814958485651.xml

Abin 提到...

To 阿凜:
要讓站內搜尋或標籤找文章只有標題,可以參考我這篇文章:標籤/搜尋頁面只列出標題 (Simplify the result of label and search),反向修改就可以變成你要的了。

Akira 提到...

Abin您好,兩個問題想請教:
第一是我照您的code將紅色部分做修改後,不知為何顯示HTML語法錯誤
我已仔細對照過,應無錯誤QQ

第二是請問有無方法讓文章中的特定段落收合?
主因是貼了好幾段的code使文章過長,想讓文章中的code部分可做收合
(個人不喜歡捲軸)

目前是用了CJH的懶人加強版

我的站是:http://guam75111-program-design.blogspot.com/

Abin 提到...

To Jason:
第一,單就你的網址沒辦法看樣板為什麼會語法錯誤,會發生這類錯誤不外乎是特殊字元、單引號雙引號、少一個標籤括號之類的,那一段會因各式樣板不同略有差異,所以在你修改的時候要檢查看看是不是有少東西(千萬不要只是複製貼上)。
第二,如果是文章中「特定一段」要收合,那我的辦法一樣可以用(就把 span 標籤括在要收合的那段程式碼裡),如果是「很多段」都要收合,那就要修改一下程式,每一個段落收合都要有自己的 unique ID、要展開時要帶入該 ID、展開和收合段落的函式 function (showDetail, hideDetail) 也要有 ID 判斷,這樣才會只展開收合特定的段落。

匿名 提到...

版主,真的很感謝你,這篇文章真的對我幫助很大。 謝謝 ^^

Unknown 提到...

版主很抱歉,我真的很努力想要學會,可是怎麼樣都弄不好,實在好挫折,因為我想要http://sabrinachenwedding.blogspot.tw/?m=0
這樣的首頁,可是語法真的難倒我了,請問現在的版本是否有些許差異,還是版主可以製作圖示讓我操作......感激不盡

張貼留言

歡迎留言或發表意見,不過要理性不做人身攻擊。匿名的朋友得到回應的速度會比較慢喔~
發問相關的禮貌和規矩請先參考這篇文章,不當留言、和本文無關的回應可能會被直接刪除無視喔!