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 排版

相关文章
相关标签/搜索