DD每週前端七題詳解-第二期

系列介紹

你盼世界,我盼望你無bug。Hello 你們好!我是霖呆呆!javascript

呆呆每週都會分享七道前端題給你們,系列名稱就是「DD每週七題」。css

系列的形式主要是:3道JavaScript + 2道HTML + 2道CSS,幫助咱們你們一塊兒鞏固前端基礎。html

全部題目也都會整合至 LinDaiDai/niubility-coding-jsissues中,歡迎你們提供更好的解題思路,謝謝你們😁。前端

正題

1、設計一個方法提取對象中全部value大於2的鍵值對並返回最新的對象

實現:java

var obj = { a: 1, b: 3, c: 4 }
foo(obj) // { b: 3, c: 4 } 複製代碼

方法有不少種,這裏提供一種比較簡潔的寫法,用到了ES10Object.fromEntries()git

var obj = { a: 1, b: 3, c: 4 }
function foo (obj) {  return Object.fromEntries(  Object.entries(obj).filter(([key, value]) => value > 2)  ) } var obj2 = foo(obj) // { b: 3, c: 4 } console.log(obj2) 複製代碼
// ES8中 Object.entries()的做用:
var obj = { a: 1, b: 2 } var entries = Object.entries(obj); // [['a', 1], ['b', 2]] // ES10中 Object.fromEntries()的做用: Object.fromEntries(entries); // { a: 1, b: 2 } 複製代碼

github.com/LinDaiDai/n…github

2、實現一個padStart()或padEnd()的polyfill

String.prototype.padStartString.prototype.padEndES8中新增的方法,容許將空字符串或其餘字符串添加到原始字符串的開頭或結尾。咱們先看下使用語法:web

String.padStart(targetLength,[padString])
複製代碼

用法:數組

'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'  // 1. 如果輸入的目標長度小於字符串本來的長度則返回字符串自己 'xxx'.padStart(2, 's') // 'xxx'  // 2. 第二個參數的默認值爲 " ",長度是爲1的 // 3. 而此參數多是個不肯定長度的字符串,如果要填充的內容達到了目標長度,則將不要的部分截取 'xxx'.padStart(5, 'sss') // ssxxx  // 4. 可用來處理日期、金額格式化問題 '12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12" '09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12" 複製代碼

polyfill實現:瀏覽器

String.prototype.myPadStart = function (targetLen, padString = " ") {
 if (!targetLen) {  throw new Error('請輸入須要填充到的長度');  }  let originStr = String(this); // 獲取到調用的字符串, 由於this本來是String{},因此須要用String轉爲字符串  let originLen = originStr.length; // 調用的字符串本來的長度  if (originLen >= targetLen) return originStr; // 如果 本來 > 目標 則返回本來字符串  let diffNum = targetLen - originLen; // 10 - 6 // 差值  for (let i = 0; i < diffNum; i++) { // 要添加幾個成員  for (let j = 0; j < padString.length; j++) { // 輸入的padString的長度可能不爲1  if (originStr.length === targetLen) break; // 判斷每一次添加以後是否到了目標長度  originStr = `${padString[j]}${originStr}`;  }  if (originStr.length === targetLen) break;  }  return originStr; } console.log('xxx'.myPadStart(16)) console.log('xxx'.padStart(16)) 複製代碼

仍是比較簡單的,而padEnd的實現和它同樣,只須要把第二層for循環裏的${padString[j]}${orignStr}換下位置就能夠了。

github.com/LinDaiDai/n…

3、用正則寫一個根據name獲取cookie中的值的方法

function getCookie(name) {
 var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]*)'));  if (match) return unescape(match[2]); } 複製代碼
  1. 獲取頁面上的cookie可使用 document.cookie 這裏獲取到的是相似於這樣的字符串:
'username=lindaidai; user-id=12345; user-roles=home, me, setting'
複製代碼

能夠看到這麼幾個信息:

  • 每個cookie都是由 name=value 這樣的形式存儲的
  • 每一項的開頭多是一個空串 ''(好比 username的開頭其實就是), 也多是一個空字符串 ' '(好比 user-id的開頭就是)
  • 每一項用 ";"來區分
  • 若是某項中有多個值的時候,是用 ","來鏈接的(好比 user-roles的值)
  • 每一項的結尾多是有 ";"的(好比 username的結尾),也多是沒有的(好比 user-roles的結尾)
  1. 因此咱們將這裏的正則拆分一下:
  • '(^| )'表示的就是獲取每一項的開頭,由於咱們知道若是 ^不是放在 []裏的話就是表示開頭匹配。因此這裏 (^| )的意思其實就被拆分爲 (^)表示的匹配 username這種狀況,它前面什麼都沒有是一個空串(你能夠把 (^)理解爲 ^它後面還有一個隱藏的 '');而 |表示的就是或者是一個 " "(爲了匹配 user-id開頭的這種狀況)
  • +name+這沒什麼好說的
  • =([^;]*)這裏匹配的就是 =後面的值了,好比 lindaidai;剛剛說了 ^要是放在 []裏的話就表示 "除了^後面的內容都能匹配",也就是非的意思。因此這裏 ([^;]*)表示的是除了 ";"這個字符串別的都匹配( *應該都知道什麼意思吧,匹配0次或屢次)
  • 有的大佬等號後面是這樣寫的 '=([^;]*)(;|$)',而最後爲何能夠把 '(;|$)'給省略呢?由於其實最後一個 cookie項是沒有 ';'的,因此它能夠合併到 =([^;]*)這一步。
  1. 最後獲取到的 match實際上是一個長度爲4的數組。好比:
[
 "username=lindaidai;",  "",  "lindaidai",  ";" ] 複製代碼
  • 第0項:全量
  • 第1項:開頭
  • 第2項:中間的值
  • 第3項:結尾

因此咱們是要拿第2項match[2]的值。

  1. 爲了防止獲取到的值是 %xxx這樣的字符序列,須要用 unescape()方法解碼。

github.com/LinDaiDai/n…

4、實現一個拖拽(兼容寫法)

考察知識點

  1. event的兼容性
  • 其它瀏覽器 window.event
  • 火狐下沒有 window.event,因此用傳入的參數 ev代替
  • 最終寫法: var oEvent = ev || window.event
  1. 實現拖拽的事件有哪些( box爲須要拖拽的元素)
  • box.onmousedown
  • document.onmousemove
  • document.onmouseup
  1. 實現的事件順序
  • 首先監聽 box.onmousedown,即鼠標按下 box時觸發的事件,記錄下鼠標按下時距離屏幕上邊和左邊的距離,以及 box距離屏幕上邊和左邊的距離,再用前者減去後者獲得差值 distanceXdistanceY
  • 而後在此事件中監聽 document.onmousemove事件,記錄下每次鼠標移動時距離屏幕上邊和左邊的距離,而後用它們減去 distanceXdistanceY,再將其賦值給 boxlefttop,使其能跟着鼠標移動
  • 不過須要考慮 box距離屏幕最上面/下面/左邊/右邊的邊界狀況
  • document.onmouseup的時候須要將 document.onmousemove事件設置爲 null

如圖所示:

Coding

css

<style>  html, body {  margin: 0;  height: 100%;  }  #box {  width: 100px;  height: 100px;  background-color: red;  position: absolute;  top: 100px;  left: 100px;  } </style> 複製代碼

html

<div id="box"></div>
複製代碼

javascript

window.onload = function () {
 var box = document.getElementById('box');  box.onmousedown = function (ev) {  var oEvent = ev || window.event; // 兼容火狐,火狐下沒有window.event  var distanceX = oEvent.clientX - box.offsetLeft; // 鼠標到可視區左邊的距離 - box到頁面左邊的距離  var distanceY = oEvent.clientY - box.offsetTop;  document.onmousemove = function (ev) {  var oEvent = ev || window.event;  var left = oEvent.clientX - distanceX;  var top = oEvent.clientY - distanceY;  if (left <= 0) {  left = 0;  } else if (left >= document.documentElement.clientWidth - box.offsetWidth) {  left = document.documentElement.clientWidth - box.offsetWidth;  }  if (top <= 0) {  top = 0;  } else if (top >= document.documentElement.clientHeight - box.offsetHeight) {  top = document.documentElement.clientHeight - box.offsetHeight;  }  box.style.left = left + 'px';  box.style.top = top + 'px';  }  document.onmouseup = function () {  document.onmousemove = null;  document.onmouseup = null;  }  } } 複製代碼

(感謝Turbo328指出使用document.onmouseup效果會比box.onmouseup好一些)

github.com/LinDaiDai/n…

5、如何阻止冒泡和默認事件(兼容寫法)

阻止冒泡:

function stopBubble (e) { // 阻止冒泡
 if (e && e.stopPropagation) {  e.stopPropagation();  } else {  // 兼容 IE  window.event.cancelBubble = true;  } } function stopDefault (e) { // 阻止默認事件  if (e && e.preventDefault) {  e.preventDefault();  } else {  // 兼容 IE  window.event.returnValue = false;  return false;  } } 複製代碼

github.com/LinDaiDai/n…

6、如何畫扇形?三角形?

/*扇形*/
.sector {  width: 0;  height: 0;  border: 100px solid red;  border-color: red transparent transparent transparent;  border-radius: 50%; } /*或者*/ .sector {  width: 100px;  height: 100px;  border: 100px solid transparent;  border-top-color: red;  box-sizing: border-box; /* 這步很重要 */  border-radius: 50%; } 複製代碼
/*三角形*/
.triangle {  width: 0;  height: 0;  border: 100px solid red;  border-color: red transparent transparent transparent; } /*或者*/ .triangle {  width: 100px;  height: 100px;  border: 100px solid transparent;  border-top-color: red;  box-sizing: border-box; } 複製代碼

github.com/LinDaiDai/n…

7、圓?半圓?橢圓?

div {
 width: 100px;  height: 100px;  background-color: red;  margin-top: 20px; } .box1 { /* 圓 */  /* border-radius: 50%; */  border-radius: 50px; } .box2 { /* 半圓 */  height: 50px;  border-radius: 50px 50px 0 0; } .box3 { /* 橢圓 */  height: 50px;  border-radius: 50px/25px; /* x軸/y軸 */ } 複製代碼

github.com/LinDaiDai/n…

後語

你盼世界,我盼望你無bug。這篇文章就介紹到這裏。

您每週也許會花48小時的時間在工做💻上,會花49小時的時間在睡覺😴上,也許還能夠再花20分鐘的時間在呆呆的7道題上,日積月累,我相信咱們都能見證彼此的成長😊。

什麼?你問我爲何系列的名字叫DD?由於呆呆呀,哈哈😄。

喜歡霖呆呆的小夥還但願能夠關注霖呆呆的公衆號 LinDaiDai 或者掃一掃下面的二維碼👇👇👇。

我會不定時的更新一些前端方面的知識內容以及本身的原創文章🎉

你的鼓勵就是我持續創做的主要動力 😊。

本文使用 mdnice 排版

相關文章
相關標籤/搜索