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)。
posted @ 2020-12-27 18:11  凉将  阅读(76)  评论(0编辑  收藏  举报