顯示具有 Blogger 標籤的文章。 顯示所有文章
顯示具有 Blogger 標籤的文章。 顯示所有文章

2025年4月2日 星期三

Blogger : 解除預覽封印

2025年4月2日 星期三

向來喜歡 Blogger 的簡單界面,又能直接寫語法,不知道哪一天它如果被 Google 收掉,會不會很不習慣其它平台的。不過,在寫程式時,Blogger 的預覽讓我有一點點困擾,它預覽時,只能看,不能「玩」,很明顯地,在我們的文件上方,有被動手腳,讓滑鼠或是觸控的事件被搶先一步,攔截走了。

昨天在發布 HTML5 FUN 最新遊戲做成的「唐詩迷宮」時,不能在預覽時,直接測試,實在覺得不快,於是追縱測試了一下,找到解除 Blogger 預覽封印的方法了!

關鍵在 class name 為「blogger-clickTrap」的元件上,只要讓它消失了,封印就自然解開,讓我的程式可以跟發布後的頁面一樣,可以自由測試。使用的 JavaScript 語法如下:

//解除預覽封印
if(/預覽/.test(document.title)) {
  setTimeout(function() {
    var clickTrap = document.querySelector('.blogger-clickTrap');
    if(clickTrap) {
      clickTrap.style.display='none';
     console.log('\n\nrelease preview click trap ...\n\n');
    }
  }, 1000);
}

哈!能自由呼吸、能跑、能跳 ...... 真是一件愉快的事。咦!這樣子,以後一些私房的小工具,不發布也能使用了。


2024年7月4日 星期四

JavaScript : 擷取 Google 日曆製作簡明行事曆

2024年7月4日 星期四

回想自己班級網站的經營歷程, 2007年起的班級網頁就改放到 Googloe Blogger。2009年那一屆更精進一些,利用 Blogger 可以自訂發布時間,時間到了,文章自動發布,用這個機置,前一天就將聯絡簿的內容打到新文章中,然後定時張貼,有學生很認真地發現了這個機置,居然一大早就上網看內容,人還沒到學校,回家功課的項都抄完了;另一個則是班級行事曆是使用 Google 日曆,在班級網站首頁中,以程式抓取日曆內容,並顯示最近的行事內容。

那幾年用的是類似這樣的網址來抓取公開的日曆內容:

http://www.google.com/calendar/feeds/日曆的ID/public/full?orderby=starttime&sortorder=ascending&alt=json-in-script&callback=listEvents&start-min=2009-01-01T00:00:00+08:00&start-max=2024-07-04T00:00:00+08:00

這兩天試了一下, 這個格式的網址已經不能用了。那有沒有替代的呢?

看到網路中的教學,大多是得使用 API key ,然後去呼叫 API。既然是公開的日曆,幹嘛還需要 API key?

觀察了一下網路中那些公開的 Google 日曆,其實它在擷取資料時,是用類似這樣的網址:

https://clients6.google.com/calendar/v3/calendars/日曆的ID/events?calendarId=日曆的ID&singleEvents=true&eventTypes=default&eventTypes=focusTime&eventTypes=outOfOffice&timeZone=Asia%2FTaipei&maxAttendees=1&maxResults=最多幾則&sanitizeHtml=true&timeMin=編碼過的開始日期時間&timeMax=編碼過的結束日期時間&key=AIzaSyBNlYH01_9Hc5S1J9vuFmu2nUqBZJNAXxs&%24unique=gc456

如果 Google 日曆是「有設為公開」的,將網址中紅色的部份置換掉,就能抓到 JSON 格式的日曆資料,剩下的,就看要輸出什麼欄位,輸出成什麼樣子了。

來試一下,直接利用 Google 日曆,輸入起始日期、顯示週數,就能製作簡明行事曆。(按這裡套用2012年範例的設定)



操作示範的影片


簡明行事曆


2023年5月15日 星期一

JavaScript : 去掉 HTML 原始碼中的程式部份

2023年5月15日 星期一

 我 Blogger 中的文章清單是讓它取每一篇文章的前 140 個字當摘要顯示,之前偷懶,沒有將 JavaScript 的程式碼去掉,摘要就被程式碼佔掉了不少字數。原來大部份的文章是沒有什麼影響,因為帶有程式碼區塊都是放文末居多,但這一次將程式碼放在最前面,可就慘了。為了解決這個問題,只好重新再調整樣版的程序,多一道將 JavaScript 程式碼去掉的步驟。

去掉 JavaScript 當然是要使用正規語法來搜尋最快,大概是這樣:

htmlString.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')

將正規語法拆解,筆記一下重點:

  • /<script\b 可以找到 <script (沒有大於符號)。
  • [^<]* 找到任何除了小於符號 < 以外的字元。
  • (?:(?!<\/script>)<[^<]*)*   找到任何字元,一直到發現 </script> 為止。
  • <\/script>/ : 找到 </script> tag.
  • /gi : 使用 g 的旗標,找到所有符合條件者;使用 i 的旗標,不分大小寫。

如果還要去掉其它所有 HTML tag 的部份,就再做一次這個規則的:

htmlString.replace(/<[^>]+>/g, '')

用這個語法找到小於符號 < 開頭,直到大於符號才停止的字串。

將去掉 JavaScript 程式碼、去掉其它 tag 和去掉換行字元及跳格字元 (\n|\r|\t) ,全部合在一起,變成:

htmlString.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '').replace(/<[^>]+>/g, '').replace(/\n|\r|\t/g, '')

哈!看似完美,我搞了個大烏龍。上面的語法是用來去掉 HTML 原始碼的,但是我原來抓文章內容是用:

post.textContent

用 textContent 就不會有 HTML tag 啊!結果當然沒有如預期去掉想刪除的部份。所以必須改為使用:

post.innerHTML

重新設定為處理過的內容也是必須使用 innerHTML。

另外,因為是放在 Blogger 的樣版中的 JavaScript ,所以特殊符號(像大於、小於、引號... )也必須先編碼過,不過會出現 XML 解析的錯誤訊息。

最後用的是:

<script type='text/javascript'>var post=document.getElementById(&quot;p<data:post.id/>&quot;), summary=post.innerHTML.replace(/&lt;script\b[^&lt;]*(?:(?!&lt;\/script&gt;)&lt;[^&lt;]*)*&lt;\/script&gt;/gi, &#39;&#39;).replace(/&lt;[^&gt;]+&gt;/g, &#39;&#39;).replace(/\n|\r|\t| /g, &#39;&#39;).substr(0,140); post.innerHTML=summary+&quot;......&quot;; </script>

有一些「眉眉角角」還是得記錄下來,太久沒用,忘得差不多了。


2023年4月25日 星期二

HTML5 : 對對碰烘焙機

2023年4月25日 星期二

HTML5 FUN 的對對碰是一個可以自訂題庫的翻牌小遊戲,牌面目前支援文字、圖片或是聲音;如果翻到同一組牌,就可加分,翻錯則扣分;牌組可以使用兩張不同的牌面(兩欄式題庫),也可以使用相同的牌面(單欄式題庫);遊戲的模式可設定為「蓋牌模式」,除了翻牌,還考記憶力。

HTML5 對對碰遊戲截圖

如果有興趣,可以在 HTML5 FUN 網站中玩玩「HTML5 對對碰」的範例題庫,網址如下:

HTML5 對對碰上一次較大的更新已是 2021年6月的事,詳情可以參考以下的舊文:

拖到 2023 年,HTML5 對對碰總算也支援「烘焙機」,可以使用 HTML5 FUN 的「烘焙機」(Blogger及網站嵌入語法產生器),只要三大步驟即可製作嵌入網頁的 HTML語法,貼入 Blogger 、Google Sites 或網頁中,即可分享使用自製的「HTML5 : 對對碰」。

【備註】最新版的「烘焙機」將所有遊戲都整合在一起了,可以按這個連結前往:


按底下的按鈕,可打開「HTML5 對對碰烘焙機」(已停止更新)來製作自己的 HTML5 對對碰遊戲:(舊版已停用)

相關連結


2022年11月22日 星期二

HTML5 : 我說你猜 : 比手畫腳

2022年11月22日 星期二

我說你猜,你說我猜;比一比,猜一猜;大家一起來比手畫腳。

比手畫腳很多人都玩過,朋友推了 TheEllenShow 頻道中的這部影片給我看:

利用平板或手機的陀螺儀(動作及方向感應器)來「翻牌」,滿方便的。2012年曾經研究過怎樣以 HTML5 加上陀螺儀來控制遊戲中的角色移動,哈!十年過去,只能重新研究,也因此,HTML5 FUN 的「 我說你猜」上線囉!

HTML5 Charades 成績報告畫面

HTML5 Charades 計時器選單畫面

特色與功能

「HTML5 我說你猜」有以下的功能與特色:

  • 以支援 HTML5 的瀏覽器來開啟頁面,即可使用,跨載具、跨平臺,不需要安裝。
  • 可以自訂題庫、題庫內容可以是文字、圖片,或是圖文混合;文字支援國字加注音的格式。
  • 可以自訂參數,例如每回合計時秒數及其它客製化的參數內容。
  • 手機、平板有陀螺儀,如果啟用感應器,目前會偵測裝置「垂直」、「往前傾」和「往後躺」三個動作,用來啟動、翻牌和表示「正確」「跳過」。
  • 在沒有動作及方向感器的電腦也可以玩,翻牌改以畫面中的按鈕操作。
  • 電腦支援「快速按鍵」預設以方向鍵右來按「正確」、「重玩」,方向鍵左來按「跳過」、「選單」,及方向鍵上下來捲動作答結果清單。(2022.11.23 明勳老師建議)
  • 有預覽題目的功能,在選定題庫後,顯示所有題目的內容,可以讓老師與學生事先討論遊戲策略。(2022.11.24 明勳老師建議)
  • 可匯入預先製作好的題庫檔案。
  • 支援語法產生器,可以將自製的遊戲嵌入 Blogger、Goolge Sites 或其它網站網頁中。

試玩與下載

教學上要如何應用,可以參考這一篇記錄:

    「HTML5 我說你猜」可以在 HTML5 FUN 網站中找到,可以試玩,或是下載打包好的程式及範例題庫;也可以使用本文章後面的「語法產器」來改題目,立即玩或是製作語法,放入自己的網站中。

    HTML5 FUN 的網址如下:

    「HTML5 我說你猜」的圖示是:

    HTML5 我說你猜的圖示

    找到圖示,按下去,即可玩範例題庫;覺得不過癮,就參考下一小節的說明,來自製遊戲吧!

    自製遊戲

    如果想製作自己的遊戲題目,又想利用手機、平板的動作偵測來控制遊戲的進行,建議使用 HTML5 FUN 烘焙機來輸入題庫,並製作語法,再將遊戲放到 Blogger 、Google Sites 或是其它有支援合法「HTTPS」的(經認證過的)網站。主要是因為較新的手機、平板系統(尤其是 iOS 12 以後),對「動作及方向感應器」的啟用,基於安全的理由,有網站的限制。

    按一下底下的按鈕,即可打開「HTML5 FUN 烘焙機」,啟動烘焙機以後,只要透過三大步驟,來更換自己的題庫,並利用「其它選項」,來做一些客製化的設定。試玩沒問題,最後就能按按鈕,輸出自製遊戲的嵌入語法。

    最新版的烘焙機請按這裡:

    Q&A

    底下將一些可能會遇的問題列出來:

    • Q:快速按鍵可以自訂嗎?
      • A:當然可以自訂快速按鍵;利用「語法產生器」中,「設定其它參數」裡的「正確時的快速按鍵名稱」和「跳過時的快速按鍵名稱」即可設定。可用的按鍵的名稱可以由主設定檔「charades_set.js 」中的「keyCodes」找到。
    • Q:為什麼無法啟用感應器?
      • A:較新的系統,像 iOS 13 以後,遊戲必須放在支援 HTTPS 的網站中才能使用感應器。
      • A:如果前一次的啟用不是按「允許」,瀏覽器會記住設定,即使按了「重新整理」也沒有用,必須要先關閉瀏覽器,重新再打開瀏覽器,才能再次設定是否允許使用感應器。
    • Q:題庫可以不要選單嗎?
      • A:可以的,有兩種方式讓遊戲跳過題目選單。
        方法1:如果題庫設定中,只有一個牌組,也就是只有一行題目,就不會出現選單。
        方法2:參考範例題庫設定檔「question-set-2.js」在題庫設定中,每一行只放一個題目,都不加任何欄位分隔符號(預設為兩個井字號),這樣子,程式會自動將每一行合成一個牌組,不用打任何分隔符號,是不是比較方便!

    相關連結

    更新記錄

    • 2023.09.22 題庫內容新增支援圖片,所以可用純文字、純圖片或是文字加圖片來當作卡片的內容。
    • 2023.09.21 遊戲結束時,停止鍵盤的監聽,以免因為連續按下一題,誤按了重玩的功能,造成成績報告被跳過,需要重玩或是回選單的功能,就以按畫面中的按鈕來執行。
    • 2023.08.18 v1.1 修改分數頁面的重玩、選單按鈕在畫面出來後兩秒才能按,以免因為連續按正確或跳過時有誤觸的情形,以致看不到答題分數及記錄。
    • 2023.08.17 v1.0 題庫支援國字加直式注音的格式。
    • 2023.07.04 v.0.9 題庫的設定如果某行沒有內容,會造成題庫解析錯誤而陷入無窮迴圈,問題已解決。
    • 2022.11.25 v.0.8 增加匯入題庫檔的功能,可以將預先製作好的題庫載入使用。
    • 2022.11.25 v.0.7 單行題庫時,未去掉第一欄的問題解決;新增 preview_col_number 的參數,用來自訂預覽時要以幾欄的方式呈現所有題目。
    • 2022.11.24 v.0.6 加入「預覽題目」的功能,如果啟用預覽,在選完題目後,會顯示所有的題目,並有 1~5 分鐘倒數計時後,自動進入該回合遊戲。
    • 2022.11.23 v.0.5 調整感應器啟用的程序,並提供更多錯誤訊息;加入快速按鍵的功能,供電腦操作。
    • 2022.11.22 程式發布。
    • 2022.11.20 HTML5 FUN charades 專案新建。 


    2022年9月25日 星期日

    HTML5 : Speaking@Blogger 語法產生器

    2022年9月25日 星期日

    HTML5 Speaking 是一個可以練習看文(圖)說話的自學小工具。學生看完提示(文字或、圖片)後,以麥克風說出答案,程式利用語音辨識的結果,來檢核答案正確與否,並給予回饋。

    HTML5 Speaking 除了可以在 HTML5 FUN 網站中下載並改成自己的練習內容;有自己的網站或是 Blog 的人,也可以利用本頁中的「語法產生器」(已停用),製作可直接放在網路上玩的版本。

    想要在 Blogger 中放自訂題庫的 HTML5 FUN Speaking 嗎?利用「HTML5 FUN 烘焙機」製作語法,再將語法貼入 Blogger 的文章中,即可以直接利用 Blogger 當儲存題庫、並讓別人來玩自製遊戲的空間囉!

    最新版的語法產生器稱為「烘焙機」,而且已經將 HTML5 FUN 大部份的遊戲整合在一個烘焙機中,可以按這個連結前往:


     

    示範影片

    [之一] 在語法產生器的題庫中加上圖片及 Vocaroo 錄製的語音




    [之二] HTML5 Speaking 語法產生器製作 Blogger 及 Weebly 頁面的方法



    相關連結

    更新記錄

    • 2022.12.06 修正加密模式語法在 Google Sites 中會有錯誤,及因為 Google Sites 使用 iFrame,無法使用 prompt 及 alert 來取得遊戲代碼及顯示訊息,所以改用自訂的輸入對話框取代。
    • 2022.10.28 加入可勾選支援 Google Sites 嵌入語法的選項。
    • 2022.10.27 加入圖形化編輯區。
    • 2022.10.16 新增 topTitle 的選項
    • 2022.10.15 新增 pinyinConvertEnable 的選項。
    • 2022.10.13 新增 order_by_random 和 ttsPlaybackRate 兩個選項供設定;解決說明對話框說明文字的填入題庫設定的問題。
    • 2022.10.08 在第三步驟加入一個可輸入「會員限定的遊戲代碼」的欄位,如果設定了,題庫會被加密,玩的時候必須先輸入正確的代碼,才能將題庫解碼,出現開始玩的按鈕。
    • 2022.10.03 將語音辨識的語言代碼、說明畫面的說明內容及遊戲模式選擇鈕上的文字,列入填寫的欄位,方便自訂;調整版面,將三大步驟以圓角邊框區分清楚。
    • 2022.09.28 解決在 iOS 時,會有按了試玩鈕,畫面不正常顯示及有按鈕無法按的情形。
    • 2022.09.25 解決語法產生單輸入的自訂題庫,因為主程式載入後,會覆蓋掉設定的問題。
    • 2022.09.25 正式發布。 


    ', html); /* &符號必須轉為 & \ 必須轉為 \\ 才能用 */ html = html.replace(/\/g, '&gt;').replace(/\\/g, '\\\\'); /* 使用 Template2 變成 Google Sites 嵌入的語法 */ html = getGoogleSitesTemplate(2).replace('', html); /* \\` 變成 \` 不然無法置換變數 */ html = html.replace(/\\\\`/g, '\\`'); /* 修正最後一個 多了一個反斜線 */ html = html.replace(/&lt;\\\\\//g, '&lt;\/').replace(/<\\\//g, '</'); } } /* =========== Google Sites 網頁語法加料完成 ===== */ break; } html = decodeHTML(html); html = html.replace(/&/g, '&').replace(//g, '>');//.replace(/\u00a0/g, ' '); html = html.replace(/^(.*)$/mg, "$1"); obj.innerHTML='
    '+html+'
    '; //select and copy if(n==2) { copyAndSelectToClipboard(obj); } } else { obj.innerHTML = ''; document.getElementById('showCodeBtn'+n).innerHTML= labelText[n]; } //reset another's innerHTML for(var i=0; i0) { questionLines = q.value; } var settingJS = document.getElementById('settingJS'); if(typeof(settingJS)!='undefined') { //由 settingJS 取得題庫設定, 並將 questionLines 的部份更新 settingJS.innerHTML = settingJS.innerHTML.replace(qRE,'$1'+"\n"+questionLines+"\n"+'$2'); } } update_settingJS = function() { var settingJS = document.getElementById('settingJS'); if(typeof(settingJS)!='undefined') { for(var i=0; i 1) ) { mimeType = 'application/octet-stream'; } else { //var mimeType = 'text/json'; } //return "data:text/json;charset=utf-8;base64," + jsonString; //return 'data:application/octet-stream;charset=utf-8;base64," + jsonString; return 'data:'+mimeType+';charset=utf-8;base64,' + dataURIString; } utf16to8 = function(str) { var out, i, len, c; out = ""; len = str.length; for(i = 0; i < len; i++) { c = str.charCodeAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { out += str.charAt(i); } else if (c > 0x07FF) { out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F)); out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F)); out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); } else { out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F)); out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); } } return out; }; base64_encode = function(data) { // http://kevin.vanzonneveld.net // + original by: Tyler Akins (http://rumkin.com) // + improved by: Bayron Guevara // + improved by: Thunder.m // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + bugfixed by: Pellentesque Malesuada // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + improved by: Rafa? Kukawski (http://kukawski.pl) // * example 1: base64_encode('Kevin van Zonneveld'); // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA==' // mozilla has this native // - but breaks in 2.0.0.12! //if (typeof this.window['btoa'] === 'function') { // return btoa(data); //} var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, enc = "", tmp_arr = []; if (!data) { return data; } do { // pack three octets into four hexets o1 = data.charCodeAt(i++); o2 = data.charCodeAt(i++); o3 = data.charCodeAt(i++); bits = o1 << 16 | o2 << 8 | o3; h1 = bits >> 18 & 0x3f; h2 = bits >> 12 & 0x3f; h3 = bits >> 6 & 0x3f; h4 = bits & 0x3f; // use hexets to index into b64, and append result to encoded string tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); } while (i < data.length); enc = tmp_arr.join(''); var r = data.length % 3; return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3); } /* 按完右上角的叉叉後,將畫面捲回輸出的區塊 */ callbackAfterClosed = function() { setTimeout( function() { var elm = document.getElementById('step3'); if (typeof(elm)!='undefined' && elm!=null) { window.scrollBy({ top: elm.offsetTop, left: 0, behavior: 'smooth' }); } },100); }; /* 將物件的 innerText 設給同層最後一個元件的 value */ setThisValue = function(elm) { if(typeof(elm.parentNode.lastChild.value)!='undefined' && elm.parentNode.lastChild.value!=null) { elm.parentNode.lastChild.value = elm.innerText; if(typeof(update_settingJS)=='function') { update_settingJS(); } } }; // //檢查 textarea 是否已存在,有就將目前的題庫及設定放進輸入區 var qIntervalID = setInterval(function() { for(var i=0; i
     
    雄::gsyan © 2009. Design by Pocket