問題:
為 Blogger 文章加入可收合 (折疊) 某段內容的按鈕,參考網上範例(Blogger 展開及收合文章)可簡單達到,但對於多個折疊內容,需多份相似的程式碼並修改對應的變數名稱,折疊內容愈多修改量愈大,每篇使用折疊功能的文章都要類似的修改。重覆代表程式碼有改善空間,站在軟體工程師的角度希望能簡化使用的流程。因此,我在這兒設計一個使用 <div> 包圍後即能指定折疊內容的方法:
由 <div class="FoldBlk"> 區塊包圍折疊內容,於區塊前動態產生按鈕,由按鈕執行 toggle 動作。折疊內容只要透過指定 <div> 即可,不需再執行額外的動作。
範例:
按線色按鈕可收合/展開下面的圖片:
此處修改 CSS 樣式來改變預設的 button 樣式:
<style> .FoldBtn { background:#507840; } .FoldBlk { background:#000000; } </style> |
為每張圖加上 <div class="FoldBlk"> </div>
<div class="FoldBlk" data-desc="萬里 - 野柳"> … </div> <div class="FoldBlk" data-desc="綠島 - 朝日溫泉" style="display: none;"> … </div> <div class="FoldBlk" data-desc="綠島 - 海中步道"> … </div> |
流程:
[1] 於 </head> 前加入 initFoldBlk 的實作:
initFoldBlk 動作為:
<1> 列舉類別為 FoldBlk 的 <div>,並在每個 <div> 前建立類別為 FoldBtn 的 <button>
<2> 註冊 FoldBtn 的 click 函數,其動作為:找此按鈕對應的 <div>,對它進行 toggle
<3> 此處下方的 <style> 指定了 FoldBlk 、FoldBtn 預設的 style
<!-- Ankas(收合按鈕#1): begin --> <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js'/> <script type='text/javascript'> //<![CDATA[ function initFoldBlk () { var strInfo; var $btn;
function getDesc (d, nextState = false) { var expandTag = "[+]"; var shrinkTag = "[-]"; var separator = " "; var strTag = ""; strInfo = d.data ("desc"); // get description from 'data-desc' attr if (!strInfo) { strInfo = ""; // No description } var style = d.css('display'); if (nextState) { strTag = (style == 'none') ? shrinkTag : expandTag; } else { strTag = (style == 'none') ? expandTag : shrinkTag; } strInfo = strInfo + separator + strTag; return strInfo; } $div = $(".FoldBlk"); $div.each (function () { var d = $(this); strInfo = getDesc (d); $btn = $("<button class='FoldBtn'>" + strInfo + "</button>"); //$btn = $("<input type='button' class='FoldBtn' value=" + strInfo + ">"); $btn.insertBefore(d); }); $(".FoldBtn").click(function() { var $clicked = $(this); var $div = $clicked.next(); strInfo = getDesc ($div, true); $(this).text (strInfo); $div.slideToggle(); }); } //]]> </script> <style> .FoldBtn { width: 100%; margin:0px; padding:2px; text-align:right; background:#E8D0A0; border:solid 1px #000000; outline:none; // Remove focus around button } .FoldBlk { margin:0px; padding:3px; background:#333333; border:solid 1px #000000; height:auto; } </style> <!-- Ankas(收合按鈕#1): end --> |
[2] 在載入文章後後呼叫 initFoldBlk():
在範本 HTML 中搜尋 <b:include cond='data:top.showPlusOne' name='googlePlusBootstrap'/>,將 initFoldBlk 置於其上方:
<!-- Ankas(收合按鈕#2): begin --> <script type='text/javascript'> initFoldBlk(); </script> <!-- Ankas(收合按鈕#2): end --> |
PS: 上面的呼叫也可在每一篇使用 .FoldBlk 的文章開頭, 程式嗎如下:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> $(document).ready(function(){ initFoldBlk(); }); </script> |
但這麼做的缺點是: 每個使用到的文章都要加上面程式碼, 不夠簡潔, 因此放在範本的 HTML 中呼叫是較好的做法。
[3] 指定要折疊的內容
對要加入收合按鈕的內容加入下面程式碼:
<div class="FoldBlk" data-desc="hello2" style="display: none;"> 要收合的內容 </div> |
o data-desc 指定顯示於收合按鈕的文字
o style="display: none;" 指定預設隱藏該段內容(視是否預設疊合來加入)
[4] 效果:
右邊文字:
+:代表可展開
-:代表可收合
結語/心得:
[1] Online resource:
http://jsfiddle.net/: 線上編寫 JS/jQuery 程式進行快速測試
[2] jQuery APIs here:
data ("desc") | get attribute: data-desc="xxx" |
css('display') | get attribute: style="display: none;" |
$btn = $("<button class='FoldBtn'>"test"</button>"); | create new element |
$btn.insertBefore($div) | insert element $btn before $div |
$div = $clicked.next(); | get next element from $clicked |
$(this).text (strInfo); | write text to $(this) |
$div.slideToggle(); | toggle $div |
$div.show(300)/hide(300) | show/hide $div |
沒有留言:
張貼留言