2021春招冲刺-1227 数组去重 | 响应式布局 | 媒体查询 |浏览器帧
2021春招冲刺
12.27日
1.JS | 数组去重
- 1.内层循环的时候比较值,如果有相同的值则跳过,不相同的值则push进组。
function unique(arr){ let newArr = [arr[0]]; for (let i = 1; i < arr.length; i++) { let repeat = false; for (let j = 0; j < newArr.length; j++) { // 判断的主要方法,当两者的数据类型相等的时候进行值的stringify转换 // 如果转换成的json数据格式相等name这两个数据相等 if(toString.call(arr[i]) == toString.call(newArr[j])){//当两个都是object的时候 if(JSON.stringify(arr[i]) == JSON.stringify(newArr[j])){ repeat = true; break; } } } if (!repeat) { newArr.push(arr[i]); } } return newArr; } window.onload=function quchong(){ var arr =[1,2,'1','2',1,null,null,undefined,undefined,{},{},[],[],[1],[1],['1'],['1'],NaN,NaN,true,true]; console.log('方法1',unique(arr)); //[1,2,'1','2',null,undefined,{},[],[1],['1'],NaN,true] };
- 2.同样使用循环方法,使用splice,当判断值相同时删去值。
function unique2(arr){ for (let i = 0; i < arr.length; i++) { for (let j = i+1; j < arr.length; j++) { if(toString.call(arr[i]) == toString.call(arr[j])){ if(JSON.stringify(arr[i]) == JSON.stringify(arr[j])){ arr.splice(j,1); j--; } } } } return arr; }
其余类似的有先排序再相邻的进行比较,但其原理大同小异,重点部分都是如何对object类型的元素进行判断。
如果能够保证数组对象中的元素不包括object对象,则可以使用数组的indexOf下标属性、数组原型对象上的includes、利用Array.from(new Set(array))
、[...new Set(arr)]
等方法进行判断,否则需要区分object类型与非object对象类型之间的比较去重。
2.CSS| 响应式布局是如何实现的
-
使用百分比展示
-
使用rem进行尺寸的展示。
rem通常用在移动端页面大小的编写上,因为移动端的屏幕尺寸往往并不固定。同样rem也有不同的设置方案,此处推荐阿里rem方案。只需要在设计师设计的图稿大小基础除100即可设置为rem大小。<script> !function(e){function t(a){if(i[a])return i[a].exports;var n=i[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var i={};return t.m=e,t.c=i,t.p="",t(0)}([function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=window;t["default"]=i.flex=function(normal,e,t){var a=e||100,n=t||1,r=i.document,o=navigator.userAgent,d=o.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i),l=o.match(/U3\/((\d+|\.){5,})/i),c=l&&parseInt(l[1].split(".").join(""),10)>=80,p=navigator.appVersion.match(/(iphone|ipad|ipod)/gi),s=i.devicePixelRatio||1;p||d&&d[1]>534||c||(s=1);var u=normal?1:1/s,m=r.querySelector('meta[name="viewport"]');m||(m=r.createElement("meta"),m.setAttribute("name","viewport"),r.head.appendChild(m)),m.setAttribute("content","width=device-width,user-scalable=no,initial-scale="+u+",maximum-scale="+u+",minimum-scale="+u),r.documentElement.style.fontSize=normal?"50px": a/2*s*n+"px"},e.exports=t["default"]}]); flex(false,100, 1); </script> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
-
使用媒体查询 @media
-
flex 弹性布局
-
使用elementui或bootstrap等的栅格式布局
-
css的grid网格布局 阮一峰css grid布局教程
3.css | 如果期望以下的div,该如何书写样式
<div class='container'></div>
- 1.在视口宽度 <=750px展示为长宽都为200px的红色方块
- 2.在视口宽度 >750px且 <=1400px 时展示为 长宽400px的蓝色方块
- 3.在视口宽度 >1400px 是展示为 长宽 600px 的黑色方块
@media screen and (max-width: 750px){ .container { background-color: red; width: 200px; height: 200px; } } @media screen and (max-width: 1400px) and (min-width: 750px){ .container { background-color:blue; width: 400px; height: 400px; } } @media screen and (min-width: 1400px){ .container { background-color:black; width: 600px; height: 600px; } }
4.浏览器 | requestIdleCallback 与 requestAnimationFrame 的作用分别是什么?有何异同?
参考博客:阮一峰-网页性能管理详解 | window.requestAnimationFrame | 参考博客1
我们首先要知道页面是一帧一帧画出来的,就和动画一样,当每秒达到60帧的时候页面看起来才会流畅,所以每一帧的时间约为16ms。
requestAnimationFrame
window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画,。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
它在每次屏幕刷新的时候执行,并且保证在每一帧内只执行一次。如果这一帧有太多任务执行,还是会造成卡顿的;因此它只能保证重新渲染的时间间隔最短是屏幕的刷新时间。
requestIdleCallback
如果说requestAnimationFrame每一帧必定会使用,那么requestIdleCallback只检测每一帧浏览器空闲的时候才执行任务。
var handle = window.requestIdleCallback(callback,options)
其中callback是回调函数,options是一个对象,里面仅支持一个属性:timeout,用于指定被调用的最后期限。当timeout时间过后浏览器依旧不空间,就会强制执行任务。
而其中callback支持传入一个参数deadline,deadline对象有一个方法和一个属性:timeRemaining() 和 didTimeout。
- didTimeout,布尔值,表示任务是否超时,结合 timeRemaining 使用。
- timeRemaining(),表示当前帧剩余的时间,也可理解为留给任务的时间还有多少。只能读不能写,而且会动态更新。因此可以不断检查这个属性,如果还有剩余时间的话,就不断执行某些任务。一旦这个属性等于0,就把任务分配到下一轮requestIdleCallback。
注意:requestIdleCallback刚刚引入标准,目前只有Chrome支持。
- 些低优先级的任务可使用 requestIdleCallback 等浏览器不忙的时候来执行,同时因为时间有限,它所执行的任务应该尽量是能够量化,细分的微任务(micro task)。
- 因为它发生在一帧的最后,此时页面布局已经完成,所以不建议在 requestIdleCallback 里再操作 DOM,这样会导致页面再次重绘。
- Promise 也不建议在这里面进行,因为 Promise 的回调属性 Event loop 中优先级较高的一种微任务,会在 requestIdleCallback 结束时立即执行,不管此时是否还有富余的时间,这样有很大可能会让一帧超过 16 ms。
引申:异步调度机制——Javascript事件循环(Event Loop)机制解析 深入理解任务异步任务执行过程,有关微任务与宏任务。
- 微任务 microtask(jobs): 当前(此次事件循环中)宏任务执行完,在下一个宏任务开始之前需要执行的任务,例如promise/ajax/Object.observe。
- 宏任务 macrotask(task):当前调用栈中执行的代码成为宏任务,例如 setTimout/script/IO/UIRendering)。