# 2023-12-11開發日誌 ## 歌: 4:00 A.M ## 單字檢測: ### 動機 本來已經做一個段落了,高一上受到補習班老師的委託增加1-6及版本的單字 又覺得本來的不夠好用 所以大改一番 --- ### 新增之功能 補習班老師給了1-6級單字託我把1-6級的單字檢測分頁做出來 所以新增資料、音標欄和網站新單字表選項和表現方式是首要之務 #### 1-6級資料整合 * 就樸實無華的進行排序 * 排序過程中發現有以下這種的格式會無法排序 ![image](https://hackmd.io/_uploads/B192iD48a.png) * 但實際搜尋下來發現也沒幾個(頂多五個左右)所以就手動處理了(複製中文=>連接=>刪除下欄) * 改變伺服器(GAS): * 基本上兩個單字本所要的其他參數(選擇個數 ,起始結尾字母)都大致相同 所以我決定就只是加上一個新的 parameter:sheet 這樣就不用做其他的判斷 * 音標顯示 * 小錯誤搞了我好久 * 本來想做成按鈕卻發現這樣挺占版面的 ### 成果 * 網站: https://watermelon-1234.github.io/memorize_voc/ * GAS端: * 檔案 * **單字涉及著作權 不公開** * CodeGs 由於增加了一本單字本,所以我決定增加單字抽取有關的引數 `var sheet = e.parameter.sheet;` 好處當然是可以直接用名子去抓sheet 不用switch-case等等的處理 主要變化 ```javascript= //只放心增或者改變的code function doGet(e)//多收request的parameter { var sheet = e.parameter.sheet; if(...) var resultArray = pickAndOutputWords(startLetter,endLetter,numToPick,sheet); //或者 else if var resultArray = pickall(startLetter,endLetter,sheet); // 执行功能 } function pickAndOutputWords(startLetter='A', endLetter='B', numToPick='5',sheetName="3-5:chosen") { && function pickall(startLetter='A', endLetter='B', sheetName="3-5:chosen") { //增加靈活性 var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName); } ``` 2. index.html * 因為自己使用下來 很明顯的再行動端(手機平板)如果滑到其他Page不理它過一陣子就會被refresh成原本的樣子了<br>阿本來單字不見就很OOXX所以我在找有沒有什麼辦法在header裡面卡refresh但感覺是沒料<br>因為這是牽涉到記憶體配置等 唯一的想法就是做成APP然後用<strong>背景APP刷新</strong>的設定等等 ```htmlembedded= <span style="font-size: 25%; color: white;">注意!如果手機切換到其他分頁或者app可能會因為手機端的記憶體空間配置而自動刷新而讓單字消失!</span> ``` * 這value設定好就不用煩惱sheet對照的問題了:> ```=htmlembeded <label for="sheetName">單字範圍</label> <select id="sheetName" > <option value="3-5:chosen">3-5級挑選版</option> <option value="1-6:chosen">1-6級挑選版</option> </select><br> ``` 3. script.js * 處理單字的開頭結尾的下式選單: ![image](https://hackmd.io/_uploads/HyD_ePfva.png) 原本:先選開始而且後面的只要超出範圍就會先變成空白要重選很麻煩 ```javascript= function populateEndLetters() {//作為下拉式選單的內容 var startLetter = document.getElementById("startLetter").value; var endLetterSelect = document.getElementById("endLetter"); var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var startIndex = alphabet.indexOf(startLetter); var endIndex = alphabet.indexOf(endLetterSelect.value); endLetterSelect.innerHTML = "<option value='' disabled selected></option>"; for (var i = startIndex; i < alphabet.length; i++) { var letter = alphabet.charAt(i); var option = document.createElement("option"); option.value = letter; option.innerText = letter; endLetterSelect.appendChild(option); } if(endIndex < startIndex) { endLetterSelect.selectedIndex = 1; } else { endLetterSelect.selectedIndex = endIndex - startIndex +1; } } ``` * 防止網頁掛掉而甚麼都不反映 使用者會很矇 ```javascript= pickAndOutputWords(startLetter, endLetter, numToPick,sheet) .then(words => { displayWords(words); }) .catch(error => { console.error('Error:', error); outputDiv.innerHTML = " ERROR: " + error+ "<br>請聯繫作者"; }); ``` * 顯示文字部分 ```javascript= function displayWords(words) { ``` 標號數字: ```javascript= content += "<tr><td class=\"ranking\"><p>"+(i+1)+".</p></td>"; ``` 英文單字 點下去要能夠跳音標 ```javascript= content += "<td><p class=\"pronouncing-switch\" data-value=\""+words[i][2].replace(/'/g, '&apos;')+"\">" + words[i][0] + "</p></td>"; ``` 複製英文單字,必須放這邊是因為 ```javascript= content += "<input type=\"button\" id=\"copyBtn\" value=\"複製單字到剪貼簿\">"; content += "<input type=\"button\" onclick=\"toggleRowVisibility(this)\" value=\"只出現不會的字\"></input>"; outputDiv.innerHTML = content; switch_col_one(); document.getElementById('copyBtn').addEventListener('click', function() { // 在這裡使用 this create_alphabat_content(); this.value = "已複製完成!"; }); } ``` * 切單字-音標 ```javascript= function col_one_unite(){ // 取得所有具有 pronouncing-switch 類別的元素 const pronouncingElements = document.querySelectorAll('.pronouncing-switch'); // 取得 body 元素的字體 const bodyFont = window.getComputedStyle(document.body).getPropertyValue("font-family"); // 為每個元素添加點擊事件監聽器 pronouncingElements.forEach(element => { const currentContent = element.textContent; const valueAttribute = element.getAttribute('data-value'); // 根據 value 屬性的第一個字元執行不同的操作 if (currentContent.startsWith('〔')) { // 如果第一個字元是 '〔',則修改字體並讓內容和 value 互換 element.textContent = valueAttribute; element.setAttribute("data-value", currentContent); // 更新內容 element.style.fontFamily = 'PHONETIC'; // 修改字體 } }); } ``` > chatgpt註解寫得真好 * 複製文字部分 前面已經在displayWord那邊放eventlistener了 所以就直接寫function了 對了 `col_one_unite();`是把所有的`class=".pronouncing-switch"`都從音標改成英文 ```javascript= function create_alphabat_content() { col_one_unite(); // 獲取指定的div元素 const targetDiv = document.getElementById('outputDiv'); // 請將'yourDivId'替換為實際的div元素ID // 獲取該div中的所有表格 const tables = targetDiv.getElementsByTagName('table'); // 如果有多個表格,選擇你想要處理的表格(例如,這裡選擇第一個表格) const targetTable = tables[0]; // 獲取該表格中所有行 const rows = targetTable.getElementsByTagName('tr'); // 創建一個空字符串,用於保存結果 let resultString = ''; // 迭代處理每一行,將第一列的textContent添加到結果字符串中 for (let i = 0; i < rows.length; i++) { const cells = rows[i].getElementsByTagName('td'); // 如果是th而不是td,請適當更改 if (cells.length > 0) { resultString += cells[1].textContent.trim() + '\n'; // 添加到結果字符串中,可以根據需要添加分隔符號 } } //this.innerHTML = "已複製完成!"; //console.log(this) // 現在resultString包含所有第一列的textContent copyToClipboard(resultString); } function copyToClipboard(content) { // 建立一個 textarea 元素 const textarea = document.createElement('textarea'); // 將內容設置為要複製的內容 textarea.value = content; // 將 textarea 加入 DOM 中 document.body.appendChild(textarea); // 選擇 textarea 中的內容 textarea.select(); try { // 嘗試複製內容到剪貼簿 const success = document.execCommand('copy'); if (!success) { console.error('無法複製到剪貼簿'); } } catch (err) { console.error('複製到剪貼簿時發生錯誤', err); } finally { // 移除 textarea document.body.removeChild(textarea); } } ``` ### 尾聲 大體上真的就這樣差不多,但應該還是可以挖大坑來填(登入系統) 這可能就不是github可以吃的 或者我要架在render之類了 如果放github語法應該會相當侷限就是 就真的每次想做任何project都是不確定是否有相關技能之下 所以邊做邊學的好處就是順便有能力增進 還有暴增解決問題方法 ~~阿壞處很明顯就是速度很慢~~ ### 同場加映 沒頭沒尾的講一下base64 主要就是加密法 好像國小就會了 #### 算法 ![image](https://hackmd.io/_uploads/HJfuswzv6.png) 不難懂就直接放圖片了 #### 用法 當然可以網路上找線上轉換: https://www.base64decode.org/ 最大的問題就是我要丟的東西如果量超大 當然貼不上去(檔案大的話就算丟txt也跑不太動(畢竟如果是把圖片轉txt大小肯定根本來的圖片不同)) 所以我們可以從<strong>CMD</strong>開搞 就是要用其中的<strong>certutil</strong> 我也不知道他的完整功能其實 有興趣就`certutil /?` ![image](https://hackmd.io/_uploads/S1ghTDfP6.png) ~~卡波真可愛~~ 主要的用法就是 `certutil -encode A.txt b.txt` 會把A檔案加密成 b.txt (b不能已存在) 當然可以改成其他檔案類型 大概長這這樣: ``` C:\Users\vagrant>type out.txt hello C:\Users\vagrant>certutil -encode out.txt hello2.txt Input Length = 6 Output Length = 66 CertUtil: -encode command completed successfully. C:\Users\vagrant>type hello2.txt -----BEGIN CERTIFICATE----- aGVsbG8K -----END CERTIFICATE----- ``` 和這樣: `certutil -decode c:\foo.asc c:\foo.exe`