問題:
為 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 | 
 
 




 
 
沒有留言:
張貼留言