接續Day 20,繼續來講解沒完成的JS部分
知識點 | 使用說明 |
---|---|
Number() | 在此將字串轉換為數字 |
filter() | 篩選符合條件的元素 |
Object.values( ) | 將物件的值放入陣列中回傳 |
Object.keys() | 將物件的屬性放入陣列中回傳 |
slice() | 擷取從起始點到終點間(不含終點)範圍內的元素 |
createElement | 在此用於創建一件複製的<textarea> 標籤 |
Clipboard.writeText | 複製的功能核心 |
async await / promise | 處理一鍵複製按鈕的非同步事件 |
//密碼生成按鈕
generateEl.addEventListener("click", () => {
let length = Number(lengthEl.value); //或 +lengthEl.value
let hasLower = lowercaseEl.checked;
let hasUpper = uppercaseEl.checked;
let hasNumber = numbersEl.checked;
let hasSymbol = symbolsEl.checked;
console.log(hasLower, hasUpper, hasNumber, hasSymbol); //布林值
resultEl.innerText = generatePassword(hasLower, hasUpper, hasNumber, hasSymbol,length);
})
變數 length
存放的是輸入框的值(如下圖),用戶輸入什麼就是什麼,另外要注意的是,因為 type="text"
,所以value傳回的值會是字串,使用 Number( )
將之轉換為數字,或是在前面加個 +
號也是可以
後面四個變數為複選框checkbox(如下圖),所以可以去檢查有沒有 checked
屬性,回傳值是布林值,有被勾選會是 true
;沒被勾選會是 false
最後的resultEl
,為密碼生成結果,因為它會受上面那五個變數影響,所以我們創建一個函式叫做generatePassword()
去接收這些變數的值,並讓他去做我們要他做的事
創建去接收用戶的選擇的函數
//擷取上段程式碼,僅為了增加易讀性
resultEl.innerText = generatePassword(hasLower, hasUpper, hasNumber, hasSymbol,length);
function generatePassword(lower, upper, number, symbol, length) {
let generatedPassword = ""; //默認下為空值
let typesCount = lower + upper + number + symbol;
let typesArr = [{ lower }, { upper }, { number }, { symbol }]
console.log(typesArr);
}
變數typesCount
是由布林值相加而成,true=1
false=0
,如下圖假設有2個輸入框被選取,就代表有2個true, typesCount
就等於2
let typesArr = [{ lower }, { upper }, { number }, { symbol }];
用來存放數筆資料,{lower}
其實跟 {lower:lower}
是一樣的,在ES6中可以簡寫為 {lower}
接著我們用 filter()
並傳入arrow function作為參數去處理 typesArr
變數
let typesArr = [{ lower }, { upper }, { number }, { symbol }].filter(
item =>Object.values(item)[0]);
上面這段程式碼拆成以下兩個知識點進行補充說明
The filter() method creates a shallow copy of a portion of a given array, filtered down to just the elements from the given array that pass the test implemented by the provided function.
擷取MDN上的解釋
陣列處理方法filter()
可以想像成麵粉拿去過篩,我們將一大包麵粉過篩去除雜質後得到一盆新的麵粉,套用在程式中,就是原陣列篩選出符合該函式條件的元素後會回傳一個新陣列給你。淺拷貝( [shallow copy](Shallow copy) )是指原資料和拷貝的新資料參考相同的記憶體位置,所以當原資料改變時,新的資料也會跟著改變,彼此沒有獨立性
語法:array.filter(function(currentValue, index, arr), thisValue)
The Object.values() method returns an array of a given object's own enumerable property values, in the same order as that provided by a for...in loop.
擷取MDN上的解釋
Object.values()
這個物件處理方法,會依照順序把物件中的值(value)放入陣列中回傳,注意O要大寫
下方是MDN上的範例
語法:Object.values(obj)
用戶選取的判斷
//以下兩個變數只是為了方便閱讀貼到這裡
let randomFunc = {
lower: getRandomLower,
upper: getRandomUpper,
number: getRandomNumber,
symbol: getRandomSymbol,
};
let typesCount = lower + upper + number + symbol;
if (typesCount === 0) {
return "";
}
for (let i = 0; i < length; i++) {
typesArr.forEach((type) => {
console.log(type); //{lower:true} {upper:true}...
let funcName = Object.keys(type)[0];
console.log(funcName); // lower upper number symbol
generatedPassword += randomFunc[funcName]();
});
}
這段稍微複雜,如果 typesCount === 0 代表用戶沒有勾選任何複選框和輸入,就會回傳空的結果
我們利用lower upper number symbol 這四個key name帶入randomFunc物件中去執行對應的函式
The Object.keys() method returns an array of a given object's own enumerable property names, iterated in the same order that a normal loop would.
擷取MDN上的解釋
Object.values()
這個物件處理方法,會依照順序把物件中的屬性(key)放入陣列中回傳,注意O要大寫
下方是MDN上的範例
語法:Object.keys(obj)
圖片來源於此
The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end (end not included) where start and end represent the index of items in that array. The original array will not be modified.
擷取MDN上的解釋
slice()
這個陣列處理方法,會以淺拷貝( [shallow copy](Shallow copy) )的方式複製從起始點到終點間(不含終點)範圍內的元素放入一個新陣列並回傳,不會修改到原陣列,下方是MDN上的範例
語法: slice(start, end)
複製按鈕
copiedEl.addEventListener("click", async () => {
let textArea = document.createElement("textarea");
let password = resultEl.innerText;
if (!password) {
return; //不執行任何操作
}
await navigator.clipboard.writeText(result.innerText);
alert("copied");
});
clipboard 指的是瀏覽器中的系統剪貼簿,要取得瀏覽器的 clipboard 物件,只要訪問 navigator 底下的 clipboard 屬性即可,執行後會回傳 Promise,我們使用async await去優化非同步語法
附上codepen連結 https://codepen.io/hangineer/pen/yLjpxVb?editors=1010
1.深度了解淺拷貝(Shallow Copy) VS 深度拷貝(Deep Copy)
這篇有很多很重要的知識點,如果要總結大概就是陣列的處理方法和promise與async await之間的關係
若有解說不夠詳盡或是錯誤歡迎指教,感激不盡!那明天見囉
50 Projects In 50 Days - HTML, CSS & JavaScript
那些被忽略但很好用的 Web API / Clipboard
不好意思,codepen上的成果按下按鈕沒有生成密碼
哈囉~我不太確定你的使用情境
但我猜是因為上圖中密碼長度欄位的10是placeholder,必須自己去手動選擇你要的密碼長度,如果沒選就按下生成按鈕,密碼長度預設為0,所以才導致密碼沒有被生成
不過後來我加上了value="10",感覺使用上會更方便一點,你可以再試試看喔!謝謝😊
原來是因為沒有手動調整密碼長度才沒有顯示出密碼,感謝回復~~