在部落格園瀏覽大牛們寫的文章時,經常會看到在文章中混有一些可執行示例,例如司徒正美的部落格中:
帶有可執行示例
可以點選“執行程式碼”
經過一番小小的探索,掌握了這種寫博技巧,希望大家也借鑑大牛們的寫法,讓我們的部落格更有表現力~開始~
一、部落格中帶有可執行javascript示例
很顯然,作者是寫了js程式碼在文章裡面了,方法也比較簡單,進入後臺編輯器的原始碼編輯模式,在裡面直接敲<script>標籤,把程式碼放進去就可以了。同理,也可以敲<style>標籤寫css程式碼。儲存後,看你的文章,已經可以有“功能”了。我之前也以為這樣就OK了,挺方便的嘛!誰知過幾天后再訪問,發現js失效了!F12檢視我的程式碼,<script>沒有了!肯定是部落格園進行過濾了。進入後臺再更新一下原始碼,發現又可以生效了,但是過幾天后就又失效了。帶著疑惑我給部落格園技術團隊發了封郵件詢問,誰知結果非常簡單,請看截圖:
真暈!所以結論是:要想在文章中使用js程式碼,請先聯絡管理員開通許可權。
二、點選“執行程式碼”,在新頁面執行文字框中的程式碼
這個就稍微有點技術含量了。我之前一直以為是部落格園有什麼外掛提供,後來發現壓根沒有,這個功能得自己用程式碼寫。基本步驟是這樣的:
①寫好HTML程式碼
②轉義,放在textarea中
③點選“執行程式碼”,建立新視窗。var win = window.open();
④獲取textarea中的程式碼,反轉義,放到win中。win.document.write(html);
這樣就可以在新視窗中執行你的程式碼了。這中間需要轉義和反轉義HTML程式碼,相關的函式如下:
//轉義 var REGX_HTML_ENCODE = /"|&|'|<|>|[\x00-\x20]|[\x7F-\xFF]|[\u0100-\u2700]/g; var encodeHtml = function(s){ return (typeof s != "string") ? s : s.replace(REGX_HTML_ENCODE, function($0){ var c = $0.charCodeAt(0), r = ["&#"]; c = (c == 0x20) ? 0xA0 : c; r.push(c); r.push(";"); return r.join(""); }); }; //反轉義 var REGX_HTML_DECODE = /&\w+;|&#(\d+);/g; var HTML_DECODE = { "<" : "<", ">" : ">", "&" : "&", " ": " ", """: "\"", "©": "©" // Add more }; var decodeHtml = function(s){ return (typeof s != "string") ? s : s.replace(REGX_HTML_DECODE, function($0,$1){ var c = HTML_DECODE[$0]; // 嘗試查表 if(c === undefined){ // Maybe is Entity Number if(!isNaN($1)){ c = String.fromCharCode(($1 == 160) ? 32 : $1); }else{ // Not Entity Number c = $0; } } return c; }); };
需要的東西就這些了,來試一下:
怎麼樣?是不是感覺瞬間高階洋氣了呢~看著雖簡單,這可是我鼓搗了半天那個編輯器才試成功的,這裡不得不吐槽一下部落格園的編輯器,太不好用了!而且還有一個重要問題:<script>標籤無法被轉義,如果程式碼中含有<script>,轉義的時候總是出錯,猜測是部落格園對script進行的特殊處理。所以,若程式碼中含有<script>標籤,只能自己手動“轉義了”,即把<換成<把>換成>並且,把所有手動轉義後的程式碼先寫在textarea中。看看我在後臺是如何寫的吧:
<textarea class="runcode" style="width: 90%; height: 100px;"><script type="text/javascript">alert(document.getElementsByTagName("li")[0].innerHTML);</script> </textarea> <script type="text/javascript"> var REGX_HTML_ENCODE = /"|&|'|<|>|[\x00-\x20]|[\x7F-\xFF]|[\u0100-\u2700]/g; var encodeHtml = function(s){ return (typeof s != "string") ? s : s.replace(REGX_HTML_ENCODE, function($0){ var c = $0.charCodeAt(0), r = ["&#"]; c = (c == 0x20) ? 0xA0 : c; r.push(c); r.push(";"); return r.join(""); }); }; var REGX_HTML_DECODE = /&\w+;|&#(\d+);/g; var HTML_DECODE = { "<" : "<", ">" : ">", "&" : "&", " ": " ", """: "\"", "©": "©" }; var decodeHtml = function(s){ return (typeof s != "string") ? s : s.replace(REGX_HTML_DECODE, function($0,$1){ var c = HTML_DECODE[$0]; // 嘗試查表 if(c === undefined){ // Maybe is Entity Number if(!isNaN($1)){ c = String.fromCharCode(($1 == 160) ? 32 : $1); }else{ // Not Entity Number c = $0; } } return c; }); }; var html = encodeHtml('<ol><li>測試的內容</li><li>測試的內容</li><li>測試的內容</li><li>測試的內容</li></ol>'); $('.runcode').prepend(html); function runcode(){ var win = window.open(); win.document.write(decodeHtml($('.runcode').html())); } </script>
沒有想到別的辦法,目前只能這麼處理了。若大家有好的方法,歡迎告知哦~
好了,就這些內容了,小夥伴們,快來試試吧~
-------------2013.08.16補充-----------------------
感謝@cnljli提供的方法。可以省掉一大片程式碼。原先在獲取到textarea中的內容後,需要經過一個反轉義函式decodeHtml將轉義後的程式碼寫到新視窗中。其實textarea的value值就可以直接取到轉義後的內容,所以這句:
win.document.write(decodeHtml($('.runcode').html()));
可以換成
win.document.write($('.runcode').val());
這樣上面那一片定義decodeHtml函式的程式碼可以不要了~漲知識了~