This is the first article I participated in beginners’ introduction

Lazy loading of images

Front knowledge

Most JavaScript deals with one of the following coordinate systems:

  • Relative to the window: similar toposition: fixed, fromwindowThe top and sides are calculated usingclientX / clientYsaid
  • Relative to the document: similar toposition: absolute, fromThe documentThe top and sides are calculated usingpageX / pageYsaid

Element coordinate

Ele. GetBoundingClientRect () to obtain the window coordinates, ele is DOMRect object, has the following properties:

  • x / yOrigin of the rectangleRelative to thewindowThe coordinates of the
  • width / heightIt’s the width and height of the rectangle
  • top / bottomIs the Y coordinate of the top/bottom rectangle edge
  • left / rightIs the X coordinate of the left/right rectangle edge

It can be concluded from the figure that:

  • left = x
  • top = y
  • right = x + width
  • bottom = y + height

Why is it neededtop / leftThis seemingly repetitive property?

The origin does not have to be the upper left corner of the rectangle. == x, top! == y

Width and height “grow” from the bottom right corner and become negative

IEDoes not supportx / y

You can either write a polyfill yourself (add a getter in domrect. prototype) or use left/top

Coordinates of theright / bottomCSS positionProperties of different

There are obvious similarities between the coordinates relative to the window and CSS position:fixed. But in CSS positioning, the right attribute represents the distance from the right edge and the bottom attribute represents the distance from the bottom edge. If we look again at the image above, we can see that this is not the case in JavaScript. All coordinates of the window are counted from the top left corner, including these coordinates.

But I don’t quite understand it yet

Document coordinates

How to get document coordinates:

  • pageY = clientY+ The height of the part of the document that scrolls out vertically
  • pageX = clientX+ Width of the section of the document that scrolls out horizontally
function getCoords(ele) {
  let rect = ele.getBoundingClientRect()

  return {
    top: rect.top + window.pageYOffset,
    right: rect.right + window.pageXOffset,
    bottom: rect.bottom + window.pageYOffset,
    left: rect.left + window.pageXOffset
  }
}
Copy the code

Image lazy loading code

Rect. top is the value relative to the top of the current window, that is, rect.top > window.innerHeight when the image is at the bottom of the document, and rect.top <= window.innerheight when the image is passing through the window

let img_list = [...document.querySelectorAll('img')]
const num = img_list.length

/** ** ** /
const img_lazy_load = (() = > {
  let cnt = 0
  return () = > {
    let deleteIndexList = []
    img_list.forEach((img, index) = > {
      let rect = img.getBoundingClientRect()
      console.log(rect.top, window.innerHeight)
      if (rect.top < window.innerHeight) {
        img.src = img.dataset.src
        deleteIndexList.push(index)
        cnt++
        if (cnt === num) {
          document.removeEventListener('scroll', img_lazy_load)
        }
      }
    })
    img_list = img_list.filter((_, index) = >! deleteIndexList.includes(index)) } })()document.addEventListener('scroll', img_lazy_load)
Copy the code

Data type judgment

Typeof can correctly recognize:

  • undefined
  • boolean
  • number
  • string
  • symbol
  • function

But for other types will be identified as the object, the use of the object. The prototype. The toString to correctly judge type, intercept [object XXXXX]] behind the object in the text and unified to lowercase:

const type_of = (obj) = > Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()

type_of(new Date()) // date
type_of({}) // object
type_of(null) // null
type_of([]) // array
Copy the code

Array to heavy

Es5, use filter to determine if the current element appears in the array for the first time:

const unique = (arr: any[]) = > {
  return arr.filter((item, index, arr) = > arr.indexOf(item) === index)
}
Copy the code

Es6, using the Set data structure for automatic de-duplication:

const unique_es6 = (arr) = > [...new Set(arr)]
Copy the code

Instead of using Set, space is used to replace time, simulating Map to store key-value pairs, time complexity O(n) :

const get_type_and_val = (obj) = > {
  if (typeof obj === 'object' && obj) {
    return Object.prototype.toString.call(obj) + JSON.stringify(obj)
  }
  return Object.prototype.toString.call(obj) + obj.toString()
}

const unique_on = (arr: any[]) = > {
  const temp = {}
  const result = []
  for (const item of arr) {
    const key = get_type_and_val(item)
    if(! temp.hasOwnProperty(key)) { result.push(item) temp[key] =true}}return result
}
Copy the code

String inversion

The main use of array join() method, reverse traversal, the last using ES6 deconstruction

const reverse_1 = (str: string) = > str.split(' ').reverse().join(' ')

const reverse_2 = (str: string) = > {
  let result = ' '
  const len = str.length
  for (let i = len - 1; i >= 0; i--) {
    result += str[i]
  }
  return result
}

const reverse_3 = (str: string) = > {
  const result = []
  const len = str.length
  for (let i = len - 1; i >= 0; i--) {
    result.push(str[i])
  }
  return result.join(' ')}const reverse_4 = (str: string) = > {
  const result = str.split(' ')
  const len = str.length
  for (let i = 0; i < len >> 1; i++) {
    [result[i], result[len - i - 1]] = [result[len - i - 1], result[i]]
  }
  return result.join(' ')}Copy the code

Array flattening

Flatten the array into one layer and add a parameter to control the number of flatten layers

[1[2], [3[4]]].flat(1) // [1, 2, 3, [4]]
[1[2], [3[4]]].flat(2) // [1, 2, 3, 4]

const flat_es6 = (arr: any[], depth? :number) = > {
  if (depth) {
    for (let i = 0; i < depth; i++) {
      if(! arr.some((item) = > Array.isArray(item))) breakarr = [].concat(... arr) } }else {
    while (arr.some((item) = > Array.isArray(item))) { arr = [].concat(... arr) } }return arr
}
Copy the code

Write in the last

This is my first article, but it has been lying in my draft box for a long time, I should have been grappling with the predecessors called “hydrology”, but in fact it is a part of my technical growth, and I’m ready for the autumn recruit only road, take the nuggets activities I released it, also hope leaders can give some advice, I am learning Dart and Flutter recently. I think MY learning process will be recorded. Please look forward to it.

Refer to javascript. The info