39
头图

Preface

Hello, everyone, I’m Lin Sanxin, is the prerequisite for advanced . In the previous article, I shared with you the 50 basic JS knowledge points I encountered during my work this year. I will give you today Share, I have encountered 50 advanced JS knowledge points in my work this year! ! !

Knowledge points

1. What is the difference between undeclared and undefined?

  • undefined: the variable is declared, but no value is assigned
  • undeclared: use directly without declaring the variable
var a; //undefined
b;    // b is not defined

2. What is the difference between let & const and var?

  • Var has variable promotion, the same variable can be declared repeatedly, and the declared variable can be changed
  • let has no variable promotion, the same variable cannot be declared repeatedly, and the declared variable can be changed
  • const has no variable promotion. You cannot declare the same variable repeatedly. The declared basic data type cannot be changed. The attribute of the reference type can be changed. You cannot just declare a variable without assigning a value.

3. Temporary dead zone problem

var a = 100;

if(1){
    a = 10;
    //在当前块作用域中存在a使用let/const声明的情况下,给a赋值10时,只会在当前作用域找变量a,
    // 而这时,还未到声明时候,所以控制台Error:Cannot access 'a' before initialization
    let a = 1;
}

4. What are the ways to get DOM elements

methoddescribeReturn type
document.getElementById(id)Get dom by idEligible dom objects
document.getElementsByTagName(tagName)Get dom by tag nameClass array composed of all dom objects that meet the conditions
document.getElementsByClassName(class)Get dom through classClass array composed of all dom objects that meet the conditions
document.getElementsByName(name)Obtain dom through the attribute name of the labelClass array composed of all dom objects that meet the conditions
document.querySelector (selector)Get dom through selectorThe first dom object that meets the criteria
document.querySelectorAll(Selector)Get dom through the selectorClass array composed of all dom objects that meet the conditions

5. What are the ways to manipulate DOM elements

titledescribe
createElementCreate a label node
createTextNodeCreate a text node
cloneNode(deep)Copy a node, along with attributes and values. When deep is true, copy together with descendant nodes. If you don’t pass or pass false, then only the current node will be copied.
createDocumentFragmentCreate a document fragment node
appendChildAppend child elements
insertBeforeInsert element in front
removeChildDelete child elements
replaceChildReplace child elements
getAttributeGet the attributes of a node
createAttributeCreate attributes
setAttributeSet node properties
romoveAttributeDelete node attributes
element.attributesGenerating attributes into array-like objects

6. What are the types of DOM?

12 kinds

元素节点              Node.ELEMENT_NODE(1)
属性节点              Node.ATTRIBUTE_NODE(2)
文本节点              Node.TEXT_NODE(3)
CDATA节点             Node.CDATA_SECTION_NODE(4)
实体引用名称节点       Node.ENTRY_REFERENCE_NODE(5)
实体名称节点          Node.ENTITY_NODE(6)
处理指令节点          Node.PROCESSING_INSTRUCTION_NODE(7)
注释节点              Node.COMMENT_NODE(8)
文档节点              Node.DOCUMENT_NODE(9)
文档类型节点          Node.DOCUMENT_TYPE_NODE(10)
文档片段节点          Node.DOCUMENT_FRAGMENT_NODE(11)
DTD声明节点            Node.NOTATION_NODE(12)

7. Scope and scope chain of JS

What is scope?

In Javascript, the scope is divided into global scope and function scope

  • Global scope: The code can be accessed anywhere in the program, and the built-in properties of the window object belong to the global scope
  • Function scope: can be accessed only in fixed code fragments

image.png

The scope has a subordinate relationship, and the determination of the subordinate relationship depends on the scope in which the function is created. As above, the bar function is created under the fn scope, then the "fn scope" is the superior of the "bar scope".

The biggest use of scope is to isolate variables. Variables with the same name under different scopes will not conflict.

What is a scope chain?

In general, the value of the variable is taken in the scope of the function that created the variable

But if the value is not found in the current scope, it will go to the superior scope until the global scope is found. The chain formed by such a search process is called the scope chain

var x = 10;

function fn(){
    console.log(x);
}

function show(f){
    var x = 20;
    f();    // 10 
}

show(fn);

image.png

8. What is the difference between array splice and slice?

methodparameterdescribe
splicesplice(start, num, item1, item2, ...)Starting from the start index, intercept num elements and insert item1 and item2 into the original array to affect the original array
sliceslice(start, end)Start from start and intercept to end-1. If there is no end, then intercept to the last element from the left, without affecting the original array

9. What is the difference between substr and substring?

methodparameterdescribe
substrsubstr(start,length)Return a substring of length length from the start position
substringsubstring(start,end)Returns the substring from the start position to the end position (not including end)

10. How is includes better than indexOf?

includes can detect NaN , indexOf cannot detect NaN , includes internally uses Number.isNaN to match NaN

11. What is the output of the following code?

for(var i = 0; i < 3; i++){
  setTimeout(function(){
      console.log(i);   
  },0); 
};

Answer: 3, 3, 3

Solution

for(let i = 0; i < 3; i++){
  setTimeout(function(){
      console.log(i);   
  },0); 
};
// 0 1 2
for (var i = 0; i < 3; i++) {
  (function(i) {
    setTimeout(function () {
      console.log(i);
    }, 0, i)
  })(i)
};
// 0 1 2

12. What is Promise? What problem was solved?

what's the function?

  • 1. Solve the problem of callback hell
  • 2. Improved code readability
  • 3. You can trust Promise, its state will only change once and is irreversible

Recommended reading

13. What is async/await? What problem was solved?

For async/await, I sum it up in one sentence async/await is the syntactic sugar of generator + Promise, it executes asynchronous code in a synchronous manner

Recommended reading

  • The usage of async/await: Ruan Yifeng's article async and await
  • The principle of async/await: Recommend my 7 pictures, the principle of async/await that can be done in 20 minutes! Why did it take so long? 【Reading: 2.1w, Like: 630】

    14. What are the commonly used regular expressions?

    Look at my article With these 25 regular expressions, the code efficiency is increased by 80%. [Read: 1.6w Like: 830]

    15. What are the methods for JS delay loading?

  • 1. <script async src="script.js"></script> : Add the async attribute to the script tag, then the process of loading and rendering subsequent document elements will be parallel to the loading and execution of script.js
  • 2. <script defer src="script.js"></script> : Add defer attribute to the script tag, and the process of loading subsequent document elements will be script.js in parallel with the loading of script.js should be completed after all elements are parsed and before the DOMContentLoaded event is triggered.
  • 3. Create script tags dynamically: When the DOMContentLoaded event is triggered, generate a script tag and render it on the page
  • 4. SetTimeout timer delays code execution

    16. Why can the new operator create an instance object?

    Analyze the entire process of new:

  • 1. Create an empty object
  • 2. Inherit the prototype of the constructor
  • 3. This points to obj and calls the constructor
  • 4. Return the object

Simply implement new:

function myNew (fn, ...args) {
    // 第一步:创建一个空对象
    const obj = {}

    // 第二步:继承构造函数的原型
    obj.__proto__ =  fn.prototype

    // 第三步:this指向obj,并调用构造函数
    fn.apply(obj, args)


    // 第四步:返回对象
    return obj
}

17. What is document fragmentation?

  • What is it: a container used to temporarily store the created dom element, created document.createDocumentFragment()
  • What's the use: Add a large number of elements that need to be added to the document fragments first, and then add the document fragments to the position that needs to be inserted, which greatly reduces dom operations and improves performance
    example

    var oFragmeng = document.createDocumentFragment(); 
    
    
    for(var i=0;i<10000;i++)
    
    { 
    
      var op = document.createElement("span"); 
    
      var oText = document.createTextNode(i); 
    
      op.appendChild(oText); 
    
      //先附加在文档碎片中
    
      oFragmeng.appendChild(op);  
    
    } 
    
    
    //最后一次性添加到document中
    
    document.body.appendChild(oFragmeng); 

    18. How does async/await detect errors?

Recommend this article async await More elegant error handling [reading: 1.5w, like: 210]

19. What are the macro tasks and micro tasks?

Macro task

#BrowserNode
I/O
setTimeout
setInterval
setImmediate
requestAnimationFrame

Micro task

#BrowserNode
Promise.prototype.then catch finally
process.nextTick
MutationObserver

20. What is the order of execution of macro tasks and micro tasks? Talk about EventLoop?

Take a look at my setTimeout+Promise+Async output sequence? It's very simple!

21. Object.defineProperty(target, key, options), what parameters can be passed in options?

  • value: set the initial value for target[key]
  • get: triggered when target[key] is called
  • set: Triggered when target[key] is set
  • writable: specifies whether target[key] can be overridden, the default is false
  • enumerable: specifies whether the key will appear in the enumeration attribute of the target, the default is false
  • configurable: specifies whether to change the options, as well as delete key attributes, default false, specific detailed look the Configurable Object.defineProperty function configuration

    22. What is anti-shake? What is throttling?

operatedescribeScenes
Anti-shakeTrigger an event frequently, but only trigger the last time. Whichever is last1. The screen rest time of the computer, the time

can be added to the frequently triggered events of the input box change 3. The anti-shake 161a2dfac351da can be added to the frequently clicked button to submit the form
ThrottlingTrigger an event frequently, but it can only be triggered once every certain period of time1. Scrolling the list of frequent requests can add throttle
2. Long press the mouse in the game, but the action is done every once in a while

23. What is a higher-order function? Simple one?

Higher-order function: English called Higher-order function. JavaScript functions actually point to a variable. Since variables can point to functions and function parameters can receive variables, then one function can receive another function as a parameter, and this kind of function is called a higher-order function.

// 简单的高阶函数
function add(x, y, f) {
    return f(x) + f(y);
}

//用代码验证一下:
add(-5, 6, Math.abs); // 11

Like the array map、reduce、filter these are all higher-order functions

24. What is function currying? Simple one?

Currying, English: Currying (sure enough, the sense of sight in English translation) is to transform a function that accepts multiple parameters into a function that accepts a single parameter (the first parameter of the original function), and returns The technique of a new function that accepts the remaining parameters and returns the result.

// 普通的add函数
function add(x, y) {
    return x + y
}

// Currying后
function curryingAdd(x) {
    return function (y) {
        return x + y
    }
}

add(1, 2)           // 3
curryingAdd(1)(2)   // 3

benefit

  • 1. Parameter reuse

    // 正常正则验证字符串 reg.test(txt)
    
    // 普通情况
    function check(reg, txt) {
      return reg.test(txt)
    }
    
    check(/\d+/g, 'test')       //false
    check(/[a-z]+/g, 'test')    //true
    
    // Currying后
    function curryingCheck(reg) {
      return function(txt) {
          return reg.test(txt)
      }
    }
    
    var hasNumber = curryingCheck(/\d+/g)
    var hasLetter = curryingCheck(/[a-z]+/g)
    
    hasNumber('test1')      // true
    hasNumber('testtest')   // false
    hasLetter('21212')      // false
  • 2. Delayed execution
    In fact, Function.prototype.bind is an example of implementation of Currying

    function sayKey(key) {
    console.log(this[key])
    }
    const person = {
    name: 'Sunshine_Lin',
    age: 23
    }
    // call不是科里化
    sayKey.call(person, 'name') // 立即输出 Sunshine_Lin
    sayKey.call(person, 'age') // 立即输出 23
    
    // bind是科里化
    const say = sayKey.bind(person) // 不执行
    // 想执行再执行
    say('name') // Sunshine_Lin
    say('age') // 23

    25. What is compose? Simple one?

    Simple compose function

    const compose = (a , b) => c => a( b( c ) );

    Example: Count the number of words

    const space = (str) => str.split(' ')
    const len = (arr) => arr.length
    
    
    // 普通写法
    console.log(len(space('i am linsanxin'))) // 3
    console.log(len(space('i am 23 year old'))) // 6
    console.log(len(space('i am a author in juejin'))) // 7
    
    
    // compose写法
    const compose = (...fn) => value => {
    return fn.reduce((value, fn) => {
      return fn(value)
    }, value)
    }
    const computedWord = compose(space, len)
    console.log(computedWord('i am linsanxin')) // 3
    console.log(computedWord('i am 23 year old')) // 6
    console.log(computedWord('i am a author in juejin')) // 7

    26. What is the difference between arrow functions and ordinary functions?

  • 1. Arrow functions cannot be used as constructors, and new cannot be used
  • 2. The arrow function does not have its own this
  • 3. The arrow function has no arguments object
  • 4. The arrow function has no prototype object

    27. What are the application scenarios of Symbol?

    Application scenario 1: Use Symbol as the object attribute name

    Usually the attributes of our objects are strings

    const obj = {
    name: 'Sunshine_Lin',
    age: 23
    }
    console.log(obj['name']) // 'Sunshine_Lin'
    console.log(obj['age']) // 23

    In fact, you can also use Symbol as the attribute name

    const gender = Symbol('gender')
    const obj = {
    name: 'Sunshine_Lin',
    age: 23,
    [gender]: '男'
    }
    console.log(obj['name']) // 'Sunshine_Lin'
    console.log(obj['age']) // 23
    console.log(obj[gender]) // 男

    However, the attribute of Symbol as an attribute will not be enumerated, which is JSON.stringfy(obj) Symbol attribute will be excluded when 061a2dfac3559f

    console.log(Object.keys(obj)) // [ 'name', 'age' ]
    for(const key in obj) {
    console.log(key) // name age
    }
    console.log(JSON.stringify(obj)) // {"name":"Sunshine_Lin","age":23}

    In fact, it is not impossible to get the Symbol attribute.

    // 方法一
    console.log(Object.getOwnPropertySymbols(obj)) // [ Symbol(gender) ]
    // 方法二
    console.log(Reflect.ownKeys(obj)) // [ 'name', 'age', Symbol(gender) ]

Application scenario 2: Use Symbol to replace constants

There are the following scenarios

// 赋值
const one = 'oneXin'
const two = 'twoXin'

function fun(key) {
  switch (key) {
    case one:
        return 'one'
      break;
    case two:
        return 'two'
      break;
  }
}

It’s okay if there are few variables, but when there are many variables, assignment and naming are very annoying, you can use the uniqueness of Symbol

const one = Symbol()
const two = Symbol()

Application scenario 3: Use Symbol to define private attributes of a class

In the following example, the PASSWORD attribute cannot be obtained in the instance

class Login {
  constructor(username, password) {
    const PASSWORD = Symbol()
    this.username = username
    this[PASSWORD] = password
  }
  checkPassword(pwd) { return this[PASSWORD] === pwd }
}

const login = new Login('123456', 'hahah')

console.log(login.PASSWORD) // 报错
console.log(login[PASSWORD]) // 报错
console.log(login[PASSWORD]) // 报错

28. What is the difference between AMD and CMD?

ModularRepresentative applicationFeatures
AMDrequire.js
by default for one or more than one. 2. Depends on the front and executes asynchronously
CMDsea.js1. CMD’s APIs are strictly differentiated, and single responsibilities are
.

29, the difference between Commonjs and ES6 Module

from 161a2dfac3570c Alibaba Tao Department technical front-end team's answer:

  • 1. Commonjs is copy output, ES6 modularization is reference output
  • 2. Commonjs is loaded at runtime, and ES6 modularization is a compile-time output interface
  • 3. Commonjs is a single value export, ES6 modularization can export multiple values
  • 4. Commonjs is a dynamic grammar that can be written in the function body, and ES6 modular static grammar can only be written at the top level
  • 5. This of Commonjs is currently modular, and this of ES6 is undefined
    Recommended article The difference between CommonJS module and ES6 module

    30. Why is Commonjs not suitable for browsers

    var math = require('math');
    
    math.add(2, 3);

    The second line math.add(2, 3) runs after the first line require('math'), so you must wait for math.js to load. In other words, if the loading time is long, the entire application will stop there and wait.

This is not a problem for the server side, because all modules are stored in the local hard disk and can be loaded synchronously. The waiting time is the read time of the hard disk. However, for the browser, this is a big problem, because the modules are all placed on the server side, and the waiting time depends on the speed of the network. It may take a long time, and the browser is in a "fake death" state.

Therefore, the browser-side module cannot use "synchronous loading" (synchronous), but can only use "asynchronous loading" (asynchronous). This is the background of the birth of the AMD specification.

31. What are the commonly used ES6-ES12 syntax?

Please see my article foundation good? Summarized 38 ES6-ES12 development skills, but to see how many points you can get? [Reading volume: 4w, like: 1.8k]

32. Is it possible for (a == 1 && a == 2 && a == 3) to be true?

Please see my article (a == 1 && a == 2 && a == 3) Is it possible to be true?

33. What is the length of the function?

Please see my article 95% of people can't answer the question: What is the length of a function?

35. MUL function in JS

MUL stands for simple multiplication of numbers. In this technique, one value is passed as a parameter to a function, and the function returns to another function, passes the second value to the function, and then repeats. For example: x y z can be expressed as

const mul = x => y => z => x * y * z

console.log(mul(1)(2)(3)) // 6

36. What is the difference between depth traversal and breadth traversal?

For the algorithm, it is nothing more than time for space and space for time.

  • 1. Depth first does not need to remember all nodes, so it takes up a small space, while breadth first needs to record all nodes first and takes a lot of space
  • 2. Depth first has a backtracking operation (you need to go back if you have no way to go), so the time will be relatively longer
  • 3. Depth-first adopts the form of stack, that is, first-in-last-out
  • 4. Breadth first adopts the form of queue, that is, first in, first out

    37. What are the design patterns in JS?

    Recommend this article: JavaScript design pattern [read: 4.4w, like: 1250]

    38. How does forEach break out of the loop?

    break can't use 061a2dfac35a01 or return to break out of the loop. Why? Students who have implemented forEach should know that the callback function of forEach forms a scope. Using return it will not jump out, but will only be regarded as continue

How to break out of the loop? You can use try catch

  function getItemById(arr, id) {
        var item = null;
        try {
            arr.forEach(function (curItem, i) {
                if (curItem.id == id) {
                    item = curItem;
                    throw Error();
                }
            })
        } catch (e) {
        }
        return item;
    }

39. How to redirect a page to another page in JS?

41. What are the mouse events?

Note: Left-right look event on the object button properties correspond 1、2、3
| Event| Description|
clickThe left button of the single-machine mouse is triggered, and the right button is invalid. When the user focuses on the button and presses Enter, it will also be triggered
dbclickDouble click the left button of the mouse to trigger, the right button is invalid
mousedownAny button of the stand-alone mouse is triggered
mouseoutTriggered when the mouse pointer is on an element and is about to move out of the element boundary
mouseoverTriggered when the mouse pointer moves out of an element to another element
mouseupTriggered when the mouse pointer moves out of an element to another element
mouseoverTriggered when any mouse button is released
mousemoveHappens continuously when the mouse is over an element
mouseenterTriggered when the mouse enters the boundary of an element
mouseleaveTriggered when the mouse leaves the boundary of an element

42. What are the keyboard events?

Note: event on the object keyCode properties, it is pressed key ASCLL value, this value discernible by which key is pressed. ASCLL table is here ASCII code list, ASCII code comparison table
| Event| Description|
onkeydownTriggered when a keyboard key is pressed
onkeyupTriggered when a keyboard key is released
onkeypressTriggered when a certain key is pressed, and does not monitor function keys, such as ctrl, shift

43. What are the coordinates of mouse events in JS?

Attributesillustratecompatibility
offsetXPosition the x-axis coordinate with the upper left corner of the current target element as the originCompatible except Mozilla
offsetYUse the upper left corner of the current target element as the origin to locate the y-axis coordinateCompatible except Mozilla
clientXPosition the x-axis coordinate with the upper left corner of the browser's visual window as the originAll compatible
clientYUse the upper left corner of the browser visual window as the origin to locate the y-axis coordinateAll compatible
pageXUse the upper left corner of the doument object as the origin to locate the x-axis coordinateCompatible except IE
pageYUse the upper left corner of the doument object as the origin to locate the y-axis coordinateCompatible except IE
screenXUse the top left corner of the computer screen as the origin to locate the x-axis coordinate (multiple screens will affect)Fully compatible
screenYUse the top left corner of the computer screen as the origin to locate the y-axis coordinateFully compatible
layerXThe nearest absolutely positioned parent element (if not, the document object), the upper left corner is the element, and the x-axis coordinate is positionedMozilla and Safari
layerYThe nearest absolutely positioned parent element (if not, the document object), the upper left corner is the element, and the y-axis coordinate is positionedMozilla and Safari

44. What are the dimensions of the element view in JS?

Attributesillustrate
offsetLeftGet the distance from the current element to the left direction of the positioned parent node
offsetTopGet the distance from the current element to the top direction of the positioned parent node
offsetWidthGet the current element width + left and right padding + left and right border-width
offsetHeightGet the current element height + up and down padding + up and down border-width
clientWidthGet the current element width + left and right padding
clientHeightGet the current element height + up and down padding
scrollWidthThe actual width of the content of the current element. If the content does not exceed the width of the box, it is the clientWidth of the box
scrollHeightThe actual height of the content of the current element. If the content does not exceed the height of the box, it is the clientHeight of the box

45. What are the dimensions of the Window view?

Attributesillustrate
innerWidthinnerWidth The width of the visible area of the browser window (not including the browser console, menu bar, and toolbar)
innerHeightinnerWidth The height of the visible area of the browser window (not including the browser console, menu bar, and toolbar)

46. What are the dimensions of the Document view?

Attributesillustrate
document.documentElement.clientWidthThe width of the visible area of the browser window (not including the browser console, menu bar, toolbar, scroll bar)
document.documentElement.clientHeightThe height of the visible area of the browser window (not including the browser console, menu bar, toolbar, scroll bar)
document.documentElement.offsetHeightGet the height of the entire document (including the margin of the body)
document.body.offsetHeightGet the height of the entire document (not including the margin of the body)
document.documentElement.scrollTopReturns the distance in the top direction of the scroll of the document (the value changes when the window is scrolled)
document.documentElement.scrollLeftReturns the distance in the scrolling left direction of the document (the value changes when the window is scrolled)

9 advanced JavaScript methods

1. getBoundingClientRect

1.1 What is

Element.getBoundingClientRect() method returns the size of the element and its position relative to the viewport. What is returned is an object with these 8 attributes: left,right,top,bottom,width,height,x,y

截屏2021-07-25 下午7.42.59.png

1.2 Compatibility

getBoundingClientRect can be used in every browser
截屏2021-07-25 下午7.45.23.png

1.3 Determine whether the element is in the visible area

This is the getBoundingClientRect , to determine whether an element appears in the viewport completely

// html

<div id="box"></div>

body {
       height: 3000px;
       width: 3000px;
      }

#box {
       width: 300px;
       height: 300px;
       background-color: red;
       margin-top: 300px;
       margin-left: 300px;
    }
    
// js

const box = document.getElementById('box')
        window.onscroll = function () {
            // box完整出现在视口里才会输出true,否则为false
            console.log(checkInView(box))
        }

function checkInView(dom) {
        const { top, left, bottom, right } = dom.getBoundingClientRect()
        console.log(top, left, bottom, right)
        console.log(window.innerHeight, window.innerWidth)
        return top >= 0 &&
                left >= 0 &&
                bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
                right <= (window.innerWidth || document.documentElement.clientWidth)
        }

According to this use, we can achieve: lazy loading and infinite scrolling

1.4 Disadvantages?

  • 1. Every scroll has to be recalculated, which will cost a lot of energy consumption
  • 2. Cause redraw backflow

2. IntersectionObserver

2.1 What is

IntersectionObserver interface provides a method for asynchronously observing the cross state of the target element and its ancestor element or the top-level document window ( viewport The ancestor element and viewport ( viewport ) is called root (root)

Popular point that: IntersectionObserver is used to monitor an element of the viewport of cross state. What is the cross state? Please see the picture below. At the beginning, the entire element is in the viewport, then the intersection of the element and the viewport is 100% , and I scroll down, only half of the element is displayed in the viewport, then the intersection of the element and the viewport The status is 50% :

截屏2021-07-25 下午9.11.41.png

2.2 Usage

// 接收两个参数 callback  option
var io = new IntersectionObserver(callback, option);

// 开始观察(可观察多个元素)
io.observe(document.getElementById('example1'));
io.observe(document.getElementById('example2'));

// 停止观察某个元素
io.unobserve(element);

// 关闭观察器
io.disconnect();

2.3 callback

callback generally has two trigger situations. One is that the target element has just entered the viewport (visible), and the other is completely out of the viewport (invisible).

var io = new IntersectionObserver(
  entries => {
    console.log(entries);
  }
);

The parameter of the callback entries ) is an array, and each member is a IntersectionObserverEntry object. For example, if the visibility of two observed objects changes at the same time, the entries array will have two members.

截屏2021-07-25 下午9.31.02.png

2.4 IntersectionObserverEntry object

{
  time: 3893.92,
  rootBounds: ClientRect {
    bottom: 920,
    height: 1024,
    left: 0,
    right: 1024,
    top: 0,
    width: 920
  },
  boundingClientRect: ClientRect {
     // ...
  },
  intersectionRect: ClientRect {
    // ...
  },
  intersectionRatio: 0.54,
  target: element
}

Attribute resolution:

  • time : The time when the visibility changed, a high-precision timestamp, in milliseconds
  • target : The target element to be observed is a DOM node object
  • rootBounds : information about the rectangular area of the root element, getBoundingClientRect() method, if there is no root element (that is, scroll directly relative to the viewport), then return null
  • boundingClientRect : Information about the rectangular area of the target element
  • intersectionRect : Information about the intersection area between the target element and the viewport (or root element)
  • intersectionRatio : The visible ratio of the target element, that is, the intersectionRect of boundingClientRect 1 , which is 061a2dfac36709 when completely visible, and less than or equal to 0

2.5 option

about the two more important attributes in the second parameter option: 161a2dfac3677d threshold and root

First talk about threshold :

threshold attribute determines when the callback function is triggered. It is an array, each member is a threshold value, the default is [0] , that is, the callback function is triggered when the intersectionRatio ) reaches 0

new IntersectionObserver(
  entries => {/* ... */}, 
  {
    threshold: [0, 0.25, 0.5, 0.75, 1]
  }
);

The user can customize this array. For example, [0, 0.25, 0.5, 0.75, 1] means that when the target element is 0%, 25%, 50%, 75%, 100% visible, the callback function will be triggered.

Let me talk about root :

The IntersectionObserver API supports scrolling within the container. root attribute specifies the container node (that is, the root element) where the target element is located. Note that the container element must be the ancestor node of the target element.

new IntersectionObserver(
  entries => {/* ... */}, 
  {
    threshold: [0, 0.25, 0.5, 0.75, 1],
    root: document.getElementById('#container')
  }
);

2.6 Complete example

body {
            height: 3000px;
            width: 3000px;
        }

#box1 {
            width: 300px;
            height: 300px;
            background-color: red;
            margin-top: 100px;
            margin-left: 300px;
        }
#box2 {
            width: 300px;
            height: 300px;
            background-color: red;
            margin-top: 100px;
            margin-left: 300px;
        }
<div id="box1"></div>
<div id="box2"></div>

const io = new IntersectionObserver(entries => {
            console.log(entries)
        }, {
            threshold: [0, 0.25, 0.5, 0.75, 1]
            // root: xxxxxxxxx
        })
io.observe(document.getElementById('box1'))
io.observe(document.getElementById('box2'))

2.7 Usage scenarios

  • 1. It can be getBoundingClientRect , and the advantage is that it will not cause redrawing
  • 2. In the same way, with the first point of function, you can do lazy loading and infinite scrolling.

2.8 Disadvantages

Don't consider this API if you want to be compatible with IE. . .
截屏2021-07-25 下午9.44.42.png

3. createNodeIterator

3.1 Get to know this API

How do I know this API? When I was interviewing, I was asked: how to traverse all the elements in the output page. I definitely thought of using loop recursion to output the first time. Interviewer: Okay, let's go home and wait for news.

Later, I went home and checked and found out the API createNodeIterator

3.2 Problem solving

Then how to use createNodeIterator to traverse and output all the elements in the page?

const body = document.getElementsByTagName('body')[0]
    const it = document.createNodeIterator(body)
    let root = it.nextNode()
    while(root) {
        console.log(root)
        root = it.nextNode()
    }

Find a website to test:

截屏2021-07-25 下午10.07.30.png

3.3 Detailed parameters

For detailed parameters, please see here , which is very detailed

3.4 Compatibility

A piece of green, use it boldly and rest assured!
截屏2021-07-25 下午10.08.43.png

4. getComputedStyle

4.1 What is

Window.getComputedStyle() method returns an object that reports the values of all CSS properties of the element after applying the active style sheet and parsing any basic calculations that these values may contain. Private CSS property values can be accessed through the API provided by the object or by simply indexing by the CSS property name.

window.getComputedStyle(element, pseudoElement)
  • element : Required, to get the style element.
  • pseudoElement : Optional, pseudo-type element. When not querying pseudo-type elements, you can ignore or pass in null.

截屏2021-07-25 下午10.23.01.png

4.2 Use

With getPropertyValue can get the specific style

// html
#box {
            width: 300px;
            height: 300px;
            background-color: yellow;
    }
    
<div id="box"></div>

const box = document.getElementById('box')
const styles = window.getComputedStyle(box)
// 搭配getPropertyValue可以获取到具体样式
const height = styles.getPropertyValue("height")
const width = styles.getPropertyValue("width")
console.log(height, width) // ’300px‘ '300px'

4.3 Compatibility

A piece of green oil. safe to use.
截屏2021-07-25 下午10.33.29.png

5. requestAnimationFrame

This article is good, introduction, usage, compatibility, all said clearly: requestAnimationFrame understanding and practice

6. requestIdleCallback

This article is good, the introduction, usage, compatibility, all said clearly: you should know requestIdleCallback

7. DOMContentLoaded

7.1 What is

When the initial HTML document is fully loaded and parsed, the DOMContentLoaded event is triggered without waiting for the stylesheet, image and subframe to be fully loaded.

At this time, the question is again, what does "the HTML document is loaded and parsed" mean? In other words, what does the browser do before the HTML document is loaded and parsed? Then we need to talk about the principle of browser rendering.

After the browser requests an HTML document from the server, it starts parsing, and the product is the DOM (Document Object Model), where the HTML document is loaded and parsed. If there is CSS, CSSOM (CSS Object Model) will be generated according to CSS, and then DOM and CSSOM will be merged to generate a render tree. With the rendering tree and knowing the styles of all nodes, the following will calculate their exact size and position in the browser based on these nodes and styles. This is the layout stage. With the above information, the node will be drawn to the browser below. All the processes are shown in the figure below:

截屏2021-07-25 下午10.49.44.png

Now you may know what the browser probably did before the HTML document is loaded and parsed, but it's not over yet, because we haven't considered JavaScript, one of the protagonists of the front-end.

JavaScript can block the generation of the DOM, which means that when the browser is parsing an HTML document, if it encounters a <script>, it will stop parsing the HTML document and process the script instead. If the script is inline, the browser will first execute the inline script, if it is external, it will first load the script and then execute it. After processing the script, the browser continues to parse the HTML document. Look at the following example:

<body>
  <script type="text/javascript">
  console.log(document.getElementById('ele')); // null
  </script>

  <div id="ele"></div>

  <script type="text/javascript">
  console.log(document.getElementById('ele')); // <div id="ele"></div>
  </script>
</body>

In addition, because JavaScript can query the style of any object, it means that after the CSS parsing is completed, that is, the CSSOM is generated, the JavaScript can be executed.

At this point, we can summarize. When there is no script in the document, the browser can trigger the DOMContentLoaded event after parsing the document; if the document contains a script, the script will block the parsing of the document, and the script can only be executed after the CSSOM is built. In any case, the triggering of DOMContentLoaded does not need to wait for pictures and other resources to be loaded.

7.2 Asynchronous script

We have been talking about the impact of synchronous scripts on web page rendering. If we want the page to be displayed as soon as possible, then we can use asynchronous scripts. HTML5 defines two methods for defining asynchronous scripts: defer and async. Let's take a look at their differences.

image.png
Synchronization script (without async or defer in the tag): <script src="***.js" charset="utf-8"></script>

If a (synchronized) script is encountered when the HTML document is being parsed, the parsing is stopped, the script is loaded first, and then executed, and the HTML document will continue to be parsed after execution. The process is as follows:

image.png

defer script: <script src="***.js" charset="utf-8" defer></script>

When the HTML document is parsed, if it encounters a defer script, the script is loaded in the background, the document parsing process is not interrupted, and after the document parsing is completed, the defer script is executed. In addition, the execution order of defer scripts is related to the position at the time of definition. The process is as follows:

image.png

async script: <script src="***.js" charset="utf-8" async></script>

If an async script is encountered when the HTML document is being parsed, the script will be loaded in the background and the document parsing process will not be interrupted. After the script is loaded, the document stops parsing, the script is executed, and the document continues to be parsed after execution. The process is as follows:

image.png

If you Google "the difference between async and defer", you may find a bunch of articles or pictures similar to the above, and here, I want to share with you the impact of async and defer on the triggering of the DOMContentLoaded event.

defer and DOMContentLoaded

If the script tag contains defer, then this piece of script will not affect the parsing of the HTML document, but will not be executed until the HTML parsing is complete. The DOMContentLoaded will only be triggered after the defer script is executed. So what does this mean? HTML document parsing is not affected. After the DOM construction is completed, the defer script is executed, but the CSSOM construction needs to be completed before the script is executed. After the DOM and CSSOM are constructed and the defer script is executed, the DOMContentLoaded event is triggered.

async and DOMContentLoaded

If the script tag contains async, the HTML document construction will not be affected. After parsing, DOMContentLoaded will be triggered without waiting for the async script execution, style sheet loading, etc.

7.3 DOMContentLoaded and load

Looking back at the first picture:

There is also a red line parallel to the blue line marked 1. The red line represents the time when the load event is triggered. Correspondingly, in the bottom overview section, there is also a red marked "Load:1.60s", which describes the load event The specific time of the trigger.

What is the difference between these two events? Click on this page and you can understand: https://testdrive-archive.azu...

To explain, DOMContentLoaded will be triggered when the HTML document is parsed, and the load event will be triggered after all resources are loaded.

Another thing to mention is that the $(document).ready(function() {// ...code... }); that we often use in jQuery is actually the DOMContentLoaded event, and $(document). load(function() {// ...code... }); The load event is monitored.

7.4 Use

document.addEventListener("DOMContentLoaded", function(event) {
      console.log("DOM fully loaded and parsed");
  });

7.5 Compatibility

One piece of green oil, feel free to use

截屏2021-07-25 下午11.00.35.png

8. MutationObserver

8.1 What

MutationObserver is a built-in object that observes DOM elements and triggers a callback when changes are detected.

8.2 Usage

// 选择需要观察变动的节点
const targetNode = document.getElementById('some-id');

// 观察器的配置(需要观察什么变动)
const config = { attributes: true, childList: true, subtree: true };

// 当观察到变动时执行的回调函数
const callback = function(mutationsList, observer) {
    // Use traditional 'for loops' for IE 11
    for(let mutation of mutationsList) {
        if (mutation.type === 'childList') {
            console.log('A child node has been added or removed.');
        }
        else if (mutation.type === 'attributes') {
            console.log('The ' + mutation.attributeName + ' attribute was modified.');
        }
    }
};

// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(callback);

// 以上述配置开始观察目标节点
observer.observe(targetNode, config);

// 之后,可停止观察
observer.disconnect();

8.3 config

config is an object with a boolean option that means "what changes will be reacted to":

  • childList - node the direct children of 061a2dfac37198,
  • subtree - node to all descendants of 061a2dfac371b9,
  • attributes —— node attributes (attribute),
  • attributeFilter —— An array of feature names, to observe only selected features.
  • characterData —— Whether to observe node.data (text content)
    Several other options:
  • attributeOldValue —— If it is true , pass both the old value and new value of the characteristic to the callback (see below), otherwise only pass the new value ( attributes option is required),
  • characterDataOldValue —— If it is true , then node.data the old and new values of 061a2dfac372cb will be passed to the callback (see below), otherwise only the new value will be passed ( characterData option is required).

    8.4 Compatibility

    截屏2021-07-25 下午11.07.52.png

    9. Promise.any

    9.1 What is

    Promise.any() receives a Promise iterable object, as long as one of the promise succeeds, it will return the already successful promise . If none of the iterable objects promise succeeds (that is, all promises fail/reject), return a failed promise and AggregateError , which is a subclass of Error and is used to group a single error together. Essentially, this method is the opposite of Promise.all()

9.2 Usage (example)

const promise1 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, 'promise 1 rejected');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 400, 'promise 2 resolved at 400 ms');
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 700, 'promise 3 resolved at 800 ms');
});

(async () => {
  try {
    let value = await Promise.any([promise1, promise2, promise3]);
    console.log(value);
  } catch (error) {
    console.log(error);
  }
})();

9.3 Compatibility

截屏2021-07-25 下午11.18.15.png

Concluding remarks

If you think this article is of little help to you, please give me a thumbs up and encourage Lin Sanxin haha. Or you can join my fish-fishing group. Let's study hard together, ah, ah, ah, ah, I will mock interviews regularly, resume guidance, answer questions and answer questions, let's learn from each other and make progress together! !
截屏2021-11-28 上午9.43.19.png


Sunshine_Lin
2.1k 声望7.1k 粉丝