你盼世界,我盼望你無bug
。Hello 你們好!我是霖呆呆!javascript
呆呆每週都會分享七道前端題給你們,系列名稱就是「DD每週七題」。css
系列的形式主要是:3道JavaScript
+ 2道HTML
+ 2道CSS
,幫助咱們你們一塊兒鞏固前端基礎。前端
全部題目也都會整合至 LinDaiDai/niubility-coding-js 的issues
中,歡迎你們提供更好的解題思路,謝謝你們😁。java
一塊兒來看看本週的七道題吧。node
(題目來源:github.com/30-seconds/…)css3
首先介紹一下題目的意思吧😄,案例🌰以下:git
const mask = (str, maskChar = '#') => {
// 代碼 } console.log(mask('123456')); // '##3456' console.log(mask('lindaidai')); // '#####idai' 複製代碼
這道題的難度應該沒有那麼大,處理方式也有不少。呆呆這邊主要是講解一下如何使用padStart
來實現的。github
簡單介紹一下padStart
方法吧,它是ES8
新增的實例函數,與它做用差很少的還有一個叫padEnd
的函數:web
String.prototype.padStart
String.prototype.padEnd
「做用」:容許將空字符串或其餘字符串添加到原始字符串的開頭或結尾。瀏覽器
「語法」:
padStart(targetLength, [padString])
複製代碼
targetLength
: 必填,當前字符串須要填充到的目標長度。若是這個數值小於當前字符串的長度,則返回當前字符串自己。
padString
: 可選,填充字符串。若是字符串太長,使填充後的字符串長度超過了目標長度,則只保留最左側的部分,其餘部分會被截斷,此參數的缺省值爲
" "
。
例如:
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab' 複製代碼
哈哈,另外想要了解如何實現一個padStart
的小夥伴能夠看呆呆以前一篇文章喲:DD每週前端七題詳解-第二期
「言歸正傳」,讓咱們回到這道題目哈,首先讓咱們來處理一下輸入參數邊界的狀況,例如輸入的str
不存在或者長度小於4
的時候:
const mask = (str, maskChar = '#') => {
if (!str || str.length <= 4) return str; } 複製代碼
其次,咱們能夠只保留住str
的末尾四個字符,而後使用padStart
將這四個字符填充至str.length
便可,以下:
const mask = (str, maskChar = '#') => {
if (!str || str.length <= 4) return str; return str.slice(-4).padStart(str.length, maskChar); } 複製代碼
slice
不會影響本來的字符串
padStart
填充便可
「介紹一下NaN」:
NaN
屬性是表明非數字值的特殊值,該屬性用於指示某個值不是數字;
NaN
是不等於
NaN
的,即
NaN === NaN
的結果是
false
;
Object.is()
來比較兩個
NaN
結果是
true
,即
Object.is(NaN, NaN)
的結果是
true
;
typeof NaN
爲
"number"
;
parseInt()
和
parseFloat()
在不能解析指定的字符串時就返回這個值;
isNaN
來判斷一個變量是否是
NaN
,它是
JS
內置對象
Number
上的靜態方法。
(關於第三點,你們能夠看一下我以前的一篇文章喲,裏面的「第二補:JS類型檢測-Object.is()和===的區別
」有提到:讀《三元-JS靈魂之問》總結,給本身的一份原生JS補給(上))
「實現一個isNaN」:
對於isNaN
的polyfill
實現起來就比較簡單了,只須要利用NaN
不等於它自身的這一點便可:
const isNaN = v => v !== v;
複製代碼
~2 = -3
?接下來,分享一道與JavaScript
原生無關的題目吧,主要也是看到羣裏有小夥伴問了關於按位取反~
的用法,這邊統一科普一下,😁。
正常一個數字,例如1
和2
,或者-1
和-2
。
若是咱們對它們進行按位取反的話,結果會是這樣:
~1 = -2
~2 = -3
~-1 = 0
~-2 = 1
看不懂不要緊,讓咱們來一步步看看實現的過程哈。
在這裏實際上是分了「正數和負數」的,由於符號不一樣取反的過程也會不一樣。
先讓咱們來看看正數的按位取反。
好比先看看~1 = -2
,過程以下:
「1. 十進制轉爲二進制原碼」
首先將十進制的1
轉化爲二進制原碼爲:0000 0001
「2. 二進制原碼按位取反」
以後將原碼按位取反:
也就是將0000 0001
=> 1111 1110
(取反應該知道啥意思吧?就是0
換成1
,1
換成0
)
「3. 取反後的二進制轉爲原碼」
再將取反後的二進制碼轉爲原碼二進制:
也就是將1111 1110
=> 1000 0010
這裏你估計看着都點懵了,當咱們將「取反後的二進制」轉爲「原碼二進制」的時候,實際上是有如下兩步的:
1
,這個第一位咱們稱之爲
「符號位」,若是是
1
的話就表示即將要轉成的數是一個負數,若是是
0
的話表示即將要轉的數是一個正數,這個符號位是不能動的;在這裏咱們能夠看到
1111 1110
的第一位是
1
,因此表示即將要轉的數是一個負數,同時咱們不動它。
+1
。因此會有這麼兩個過程:
1111 1110
=>
1000 0001
1000 0001
=>
1000 0010
(這步是對上一步的結果
+1
,由於上一步的最後一個數是
1
,因此它再加上
1
就須要向前進一位了,所以變成了
1000 0010
)
「4. 將原碼二進制轉爲十進制」
最後一步就是將咱們前面獲得的1000 0010
這個二進制轉化爲十進制了。
第一位符號位,是1
,則表示是個負數,因此結果爲-2
。
OK👌,搞懂了這個步驟以後再讓咱們本身來轉換一下~2 = -3
吧:
1. 0000 0010 2. 1111 1101 3. 1000 0011 4. -3 複製代碼
「正數按位取反總結」
負數的按位取反和上面就有些不同了,主要是第二步和第三步調換一下順序:
例如:~-1 =0
的轉換過程:
「1. 十進制轉爲二進制原碼」
這步和正數按位取反是同樣的:
-1
=> 1000 0001
「2. 符號位保留,其他位取反+1」
轉換過程:
1000 0001
=>
1111 1110
(取反)
1111 1110
=>
1111 1111
(取反後 + 1)
「3. 二進制原碼按位取反」
將剛剛獲得的再進行按位取反:
1111 1111
=> 0000 0000
「4. 二進制原碼轉爲十進制」
0000 0000
=> 0
OK👌,如今本身來轉換一下~-2 = 1
吧:
1. 1000 0010 2. 1111 1110 3. 0000 0001 4. 1 複製代碼
這裏沒啥訣竅,關鍵就是要記住轉換的過程而後不斷的練習吧 😂。
另外關於~~
的用法還能夠看呆呆的另外一篇文章喲《JS中按位取反運算符~及其它運算符》
insertAdjacentHTML
方法嗎?這個方法是呆呆最近在看公司項目代碼時瞭解到的,以前一直沒有注意它。
首先對於它的用法:
「
insertAdjacentHTML()
」 方法將指定的文本解析爲Element
元素,並將結果節點插入到DOM樹中的指定位置。它不會從新解析它正在使用的元素,所以它不會破壞元素內的現有元素。這避免了額外的序列化步驟,使其比直接使用innerHTML操做更快。
其次它的做用對象是一個元素element
,例如const container = document.getElementById('container')
語法上呢:
element.insertAdjacentHTML(position, text);
複製代碼
position
:一個
DOMString
,也就是表示插入內容相對元素的位置,且必須是下面的字符串之一:
'beforebegin'
:元素自身的前面。
'afterbegin'
:插入元素內部的第一個子節點以前。
'beforeend'
:插入元素內部的最後一個子節點以後。
'afterend'
:元素自身的後面。
text
:是要被解析爲HTML或XML元素,並插入到DOM樹中的
DOMString
。
「案例」:
讓咱們來看看它的用法,例如🌰如今有一個HTML
的結構爲:
<div id="one">我是one</div>
複製代碼
JavaScript
代碼中加上這段話:
const one = document.getElementById('one');
one.insertAdjacentHTML('afterend', '<div id="two">我是two</div>'); 複製代碼
如今最終的渲染結果就變成了這樣:
<div id="one">我是one</div><div id="two">我是two</div>
複製代碼
「工做上的用法」:
在項目中,主要能夠應用於這樣的場景:一個空的容器(你能夠理解爲一個div
),開始須要一個loading
的效果,在數據加載完畢以後,須要把loading
取掉且清空容器內的元素並以其它方式從新渲染出容器的內容。
這裏呆呆就以定時器來模擬一下數據加載的過程,實現代碼以下:
<body>
<div id="container"></div> </body> <script> const container = document.getElementById('container'); const loading = '<div id="loading">loading</div>'; // loading多是一個組件 container.insertAdjacentHTML('beforeend', loading); setTimeout(() => { container.innerHTML = '' }, 2000) </script> 複製代碼
(固然,咱們不要爲了刻意用而去用,適合本身的纔是最好的)
「安全問題」:
使用 insertAdjacentHTML
插入用戶輸入的HTML內容的時候,須要轉義以後才能使用。
例如:
const one = document.getElementById('one');
// 因爲 encodeURI('<div id="two">我是two</div>')會被轉譯爲: // %3Cdiv%20id=%22two%22%3E%E6%88%91%E6%98%AFtwo%3C/div%3E // 所以最終會被當成 "%3Cdiv%20id=%22two%22%3E%E6%88%91%E6%98%AFtwo%3C/div%3E"字符串渲染 one.insertAdjacentHTML('afterend', encodeURI('<div id="two">我是two</div>')); 複製代碼
若是隻是爲了插入文本內容(而不是HTML節點),不建議使用這個方法,建議使用node.textContent
或者 node.insertAdjacentText()
。由於這樣不須要通過HTML解釋器的轉換,性能會好一點。(這裏是引用的MDN-insertAdjacentHTML上的內容)
insertAdjacentHTML
和insertAdjacentElement
的區別第二個參數的類型不一樣, 前者接收的是是要被解析爲HTML或XML元素的字符串
,然後者接收的是一個element
元素。
const one = document.getElementById('one');
one.insertAdjacentHTML('afterend', '<div id="two">我是two</div>'); const one = document.getElementById('one'); const two = document.createElement('div') two.innerHTML = '我是two'; one.insertAdjacentElement('afterend', two); 複製代碼
實現效果以下:
先來看一下HTML
方面的代碼:
<div id="container">
<div class="item item-1">1</div> <div class="item item-2">2</div> <div class="item item-3">3</div> <div class="item item-4">4</div> <div class="item item-5">5</div> <div class="item item-6">6</div> <div class="item item-7">7</div> <div class="item item-8">8</div> <div class="item item-9">9</div> </div> 複製代碼
還有一些item
上的基礎css
代碼:
#container {
/* css代碼 */ } .item { font-size: 2em; text-align: center; border: 1px solid #e5e4e9; } .item-1 { background-color: #ef342a; } .item-2 { background-color: #f68f26; } .item-3 { background-color: #4ba946; } .item-4 { background-color: #0376c2; } .item-5 { background-color: #c077af; } .item-6 { background-color: #f8d29d; } .item-7 { background-color: #b5a87f; } .item-8 { background-color: #d0e4a9; } .item-9 { background-color: #4dc7ec; } 複製代碼
「方案一」:
第一種方案可使用浮動+百分比:
#container {
width: 150px; height: 150px; } .item { float: left; width: 33.33%; height: 33.33%; box-sizing: border-box; font-size: 2em; text-align: center; border: 1px solid #e5e4e9; } 複製代碼
「方案二」:
還可使用flex
佈局的方式:
#container {
width: 150px; height: 150px; display: flex; flex-wrap: wrap; } .item { width: 33.33%; height: 33.33%; box-sizing: border-box; font-size: 2em; text-align: center; border: 1px solid #e5e4e9; } 複製代碼
「方案三」:
另外的話,也許還能夠試試grid
?
#container {
display: grid; grid-template-columns: 50px 50px 50px; grid-template-rows: 50px 50px 50px; } .item { font-size: 2em; text-align: center; border: 1px solid #e5e4e9; } 複製代碼
will-change
是CSS3
新增的標準屬性,它的做用很單純,就是"加強頁面渲染性能"
,當咱們在經過某些行爲觸發頁面進行大面積繪製的時候,瀏覽器每每是沒有準備,只能被動的使用CPU去計算和重繪,因爲事先沒有準備,對於一些複雜的渲染可能會出現掉幀、卡頓等狀況。
而will-change
則是在真正的行爲觸發以前告訴瀏覽器可能要進行重繪了,至關於瀏覽器把CPU拉上了,能從容的面對接下來的變形。
經常使用的語法主要有:
whil-change: scroll-position;
即將開始滾動
will-change: contents;
內容要動畫或者變化了
will-transform;
transform相關的屬性要變化了(經常使用)
注意:
will-change
雖然能夠開啓加速,可是必定要適度使用
hover
中,這樣移出元素的時候就會自動
remove
掉
will-change
了
JS
添加了
will-change
,注意要及時
remove
掉,方式就是
style.willChange = 'auto'
知識無價,支持原創。
參考文章:
你盼世界,我盼望你無bug
。這篇文章就介紹到這裏。
您每週也許會花48
小時的時間在工做💻上,會花49
小時的時間在睡覺😴上,也許還能夠再花20
分鐘的時間在呆呆的7道題上,日積月累,我相信咱們都能見證彼此的成長😊。
什麼?你問我爲何系列的名字叫DD
?由於呆呆
呀,哈哈😄。
喜歡「霖呆呆」的小夥還但願能夠關注霖呆呆的公衆號 LinDaiDai
或者掃一掃下面的二維碼👇👇👇。
我會不定時的更新一些前端方面的知識內容以及本身的原創文章🎉
你的鼓勵就是我持續創做的主要動力 😊。
本文使用 mdnice 排版