# 2023-12-11開發日誌
## 歌: 4:00 A.M
## 單字檢測:
### 動機
本來已經做一個段落了,高一上受到補習班老師的委託增加1-6及版本的單字
又覺得本來的不夠好用 所以大改一番
---
### 新增之功能
補習班老師給了1-6級單字託我把1-6級的單字檢測分頁做出來
所以新增資料、音標欄和網站新單字表選項和表現方式是首要之務
#### 1-6級資料整合
* 就樸實無華的進行排序
* 排序過程中發現有以下這種的格式會無法排序

* 但實際搜尋下來發現也沒幾個(頂多五個左右)所以就手動處理了(複製中文=>連接=>刪除下欄)
* 改變伺服器(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
* 處理單字的開頭結尾的下式選單:

原本:先選開始而且後面的只要超出範圍就會先變成空白要重選很麻煩
```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, ''')+"\">" + 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
主要就是加密法
好像國小就會了
#### 算法

不難懂就直接放圖片了
#### 用法
當然可以網路上找線上轉換:
https://www.base64decode.org/
最大的問題就是我要丟的東西如果量超大
當然貼不上去(檔案大的話就算丟txt也跑不太動(畢竟如果是把圖片轉txt大小肯定根本來的圖片不同))
所以我們可以從<strong>CMD</strong>開搞
就是要用其中的<strong>certutil</strong>
我也不知道他的完整功能其實 有興趣就`certutil /?`

~~卡波真可愛~~
主要的用法就是
`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`