在博客園瀏覽大牛們寫的文章時,經常會看到在文章中混有一些可運行示例,例如司徒正美的博客中:
帶有可運行示例
可以點擊“運行代碼”
經過一番小小的探索,掌握了這種寫博技巧,希望大家也借鑒大牛們的寫法,讓我們的博客更有表現力~開始~
一、博客中帶有可運行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函數的代碼可以不要了~漲知識了~