2007/09/20

特效顯示"繼續閱讀"功能

最近忍不住手養,在自己的Blog裡面加了一些酷炫的功能,雖然有點違背我的初衷,讓我一時迷失了Blog的方向,不過,偶爾玩玩也不錯唄!
這個"繼續閱讀"的Hack,可以到OVER30-MAN的Blog首頁,按下每篇文章後面的"繼續閱讀"圖示,看看它的特效,很炫吧!今天就是要告訴各位如何做成的。
站在巨人的肩膀上:
當然在寫這篇之前,一定要先告訴各位,我們是站在哪些巨人的肩膀上。Ramani的Hackosphere,是這個"Peekaboo-view文章展開功能"的發源地。國內的話,大家可以先去看看Kaie大的Blog,看看他的[+/-]Read More ....功能。基本上,OVER30-MAN就是基於Kaie大的這一篇文章,延伸發展出來的,所以請各位一定要去閱讀,後續的才好說明。請大家先比較一下兩種"繼續閱讀"功能的差異性,最明顯的就是Kaie大的一下子就"閃"出來了,不仔細看,有時會讓人搞不清楚現在到底讀到什麼地方了。因此才會有修改成現在這種特效顯現方式的念頭,比較能讓人明白,文章該從哪個地方開始繼續閱讀下去。
另外,要達到這樣的特效,還需要Prototype Javascript Library。請大家自行去下載一份回來玩玩吧!順便熟悉一下使用的方法,並衷心的感謝這些巨人們,讓我們不必花費這麼多的心力在這上面。


遇到的問題:
假設大家都很聽話的看完了Kaie大的文章了。基本上,它的運作方式,就是去找 id="fullpost"的<span>標籤,然後將它style中的dispaly屬性,從原來的none改成inline。接著再來看Prototype Javascript Library提供的特效吧!建議直接去看看下載回來的範例HTML程式碼,就知道怎麼用了,如OVER30-MAN是用Effect.Appear(id),就是把要顯示的部份,其id放到函式裡面,其他的就交給函式去處理。所以,很簡單啊!只要將原程式碼有關id ="fullpost"那一段的span[i].style.display = "inline";拿掉,改成Effect.Appear("fullpost"),就好啦!事情不是憨人想的這麼簡單滴!
  1. 不可以這麼作,最主要的原因,就是Effect函式,只認id,所以當我們放在首頁的post,除非只放一篇,要不然有多個id = "fullpost"(別忘了每篇文章中都有<span id="fullpost">隱藏的部份</span>),它會每次都去找第一個來執行,所以這是行不通的。
  2. 經過測試,Effect函式,對於<span>的作用好像不是很好,對<div>的就很正常,因此,原程式用<span>標籤來隱藏文章,也需改成用<div>標籤
  3. 在Template程式碼中,有一行<style>#fullpost {display:none;}</style>,使得特效無法顯示,原因為何,還想不出來,頭腦有點亂。如果將這一行拿掉,改成每篇文章中寫<span style="display:none;" id="fullpost">隱藏的部份</span>,特效就可以正常顯示了,但是,當按下title來連結時,被隱藏的部份,就無法顯示了。
解決問題:
好吧!問題還是要解決,為了我的網頁特效。先說明OVER30-MAN並不是程式達人,只是看得懂程式碼,也沒有深入去了解Javascript中可用的方法,所以可能有更好的方式可以解決,而我單純的用點小技巧,避免掉上述的問題,就是解決之道。
  1. 針對問題一:看來唯一的方法,就是給它一個獨有的id,但是這唯一的id去哪裡生呢?咦!每按一次"繼續閱讀",不是都會傳回這一篇文章的id嗎?(post-xxxxxxxxxxx),這應該是獨一無二的吧!然後再把這個id,加工一下,變成fullpost-xxxxxxxxx(避免和文章本身的id重覆),丟給隱藏部份當作新的id就好了,這樣一來,這個問題就解決了,不過要注意的是,特效執行完後,還是要改回原來的fullpost,以便給後續的特效使用。
  2. 針對問題二:好消息是,只要將<span>標籤,改成<div>標籤就可以了,壞消息是,如果你已經有1000篇文章使用舊的<span>標籤方式,你就要一篇一篇的改,想開一點,你可以好好重溫你的舊文章,消極一點,就讓它去吧!反正它們也不會再回到首頁了!
  3. 針對問題三:還是用javascript來解決。在拑入Template程式碼部分,最後面有單獨執行一個checkFull()的函式,老實說我沒有去想這函式是幹什麼用的,不過,何不在這裡將所有有id="fullpost"的部份,隱藏起來呢?果然可以解決。
加入程式碼:
好了,講解完畢,接著就自己動手把該貼的程式碼貼一貼,然後試試看動作正不正常囉!
STEP1.
在你下載回來的Prototype Javascript Library資料夾中,找到prototype.js和effects.js兩個檔案,將他們上傳到自己的網站空間,建議去申請一個Google Pages,方便又好用,最重要的是,如果大家都連到共用的網站去讀取這些檔案,速度肯定很慢,自己用自己的,才有效率。
STEP2.
在Template中的<head>和</head>之間,加入下列的程式碼

<script src='http://xxxxxxxxx.googlepages.com/prototype.js' type='text/javascript'/>
<script src='http://xxxxxxxxx.googlepages.com/effects.js' type='text/javascript'/>

<script type='text/javascript'>
function showFull(id)
{
var post = document.getElementById(id);
var spans = post.getElementsByTagName('div');
for (var i = 0; i &lt; spans.length; i++)
{
if (spans[i].id == "fullpost")
{
var newId = "full" + id; //製作獨一無二的id
spans[i].id = newId; //取代原來的fullpost
Effect.Appear(newId); //執行特效
spans[i].id = "fullpost"; //改回原來的id
}
if (spans[i].id == "showlink")
spans[i].style.display = 'none';
if (spans[i].id == "hidelink")
spans[i].style.display = 'inline';
}
}

function hideFull(id)
{
var post = document.getElementById(id);
var spans = post.getElementsByTagName('div');
for (var i = 0; i &lt; spans.length; i++)
{
if (spans[i].id == "fullpost")
{
var newId = "full" + id;
spans[i].id = newId;
Effect.Fade(newId);
spans[i].id = "fullpost";
}
if (spans[i].id == "showlink")
spans[i].style.display = 'inline';
if (spans[i].id == "hidelink")
spans[i].style.display = 'none';
}
post.scrollIntoView(true);
}

function checkFull(id)
{
var post = document.getElementById(id);
var spans = post.getElementsByTagName('div');
var found = 0;
for (var i = 0; i &lt; spans.length; i++)
{
if (spans[i].id == "fullpost")
{
found = 1;
spans[i].style.display = 'none'; //執行特效前,先隱藏起來
}
if ((spans[i].id == "showlink") &amp;&amp; (found == 0))
spans[i].style.display = 'none';
}
}
</script>

連到prototype.js和effects.js的網址,請根據本身狀況更改。另外就是特效的部份,這裡是用Effect.Appear()展開,Effect.Fade()收起。你可以自行參考範例檔,然後選出自己最喜歡的特效模式,套用進去即可。
STEP3.
接下來要"展開小裝置範本",找到下面這一段,加入紅色這一段


<b:includable id='post' var='post'>
<div class='post' expr:id='"post-" + data:post.id'>
<a expr:name='data:post.id'/>



STEP4.
同樣也是找到下面這一段文字,然後將紅色部分加入


<div class='post-header-line-1'/>
<div class='post-body'>
<b:if cond='data:blog.pageType == "item"'>
<p><data:post.body/></p>
<b:else/>
<p><data:post.body/></p>
<div id='showlink'>
<p><a href='javascript:void(0);'
expr:onclick='"javascript:showFull(\"post-" +
data:post.id + "\");"'>繼續閱讀...</a></p>
</div>
<div id='hidelink' style='display:none'>
<p><a href='javascript:void(0);'
expr:onclick='"javascript:hideFull(\"post-" +
data:post.id + "\");"'>結束閱讀...</a></p>
</div>
<script type='text/javascript'>
checkFull("post-" + "<data:post.id/>");
</script>
</b:if>
<div style='clear: both;'/> <!-- clear for photos floats --></div>


其中,"繼續閱讀..."以及"結束閱讀...",就是你可以自行更改的"展開"和"收起"的顯示文字,請依你的喜好,甚至用圖片都可以。
好了,大功告成,不過還是不得不提醒你,以後你在寫文章的時候別忘了使用<div id="fullpost">隱藏的部份</div>來取代原有的<span>標籤哦!報告完畢!
UPDATE(2007.09.21):
  1. 所謂平時不爬文,吃虧在眼前,原來Ramani他老兄,早就已經寫出來啦!真是一整個無力,害我還搞了那麼久,看來有很多人跟我有一樣的感覺,就是顯示的太快了,會讓人困惑。不過,OVER30-MAN的做法與Ramani不太一樣,至少讓我這個已經OVER30的腦袋動了一整天,還算小有收穫啦!就不怨嘆了!
  2. 另外,關於用<span>標籤會有什麼影響,OVER30-MAN又測試了一次,大致上影響不大,除了文章裡面有圖片的話,在做Effect.Appear()及Effect.Fade()特效的時候,圖片的透明度(opacity)不會跟著文字一起變,簡單的說,就是文字慢慢淡出的時候,圖片還是很清楚的意思啦!如果你不介意的話,其實差別不大。

沒有留言:

Template Designed by Douglas Bowman - Updated to New Blogger by: Blogger Team
Modified for 3-Column Layout by Hoctro - Now Used by OVER30-MAN