When we deal with the buried point of module exposure, we need to judge whether the module is visible (exposed) according to the position of page scrolling. The traditional method on the Web is to add a page Scroll monitoring event and judge by comparing the scrolling position with the module position. This method can also be used in small programs, but now there is a more convenient and elegant alternative — IntersectionObserver object.

IntersectionObserver object

IntersectionObserver object, which is used to infer whether certain nodes can be seen by users. Relevant APIS are introduced below:

(1) to create

By enclosing createIntersectionObserver created, this method can be introduced to three parameters:

  • Thresholds: array of values, representing the threshold of the intersection ratio (there can be multiple, the value range[0, 1]), a listening callback will be triggered when the intersection reaches this threshold, which is set to the middle position in the exposure buried point scenario[0.5]Can;

  • InitialRatio: the initial intersection ratio. If the intersection ratio detected during method call is not equal to this value and reaches the threshold, a listener callback function will be triggered, and the default value 0 will be set in the scenario of exposure buried point.
  • ObserveAll: whether to observe multiple target nodes at the same time;

(2) Set reference area

There are two methods to set the reference region: io.relativeToViewPort () and io.relativeto (‘selector’, {… Margins}), if the intersection reference area is a window, use the first one. The latter can use a selector to set other nodes as reference areas for intersection.

(3) to monitor

Observe (selector, callback). The selector of the target module will trigger the callback function when its intersection with the reference area reaches a threshold ratio. The callback function takes the following parameters (which are not used in this scenario) :

  • IntersectionRatio: intersecting ratio of the two;
  • Time: indicates the timestamp of the intersection detection.
  • Various boundaries:
    • IntersectionRect: intersecting area boundary;
    • BoundingClientRect: target boundary;
    • RelativeRect: the boundary of the reference area;

(4) Cancel monitoring

Remember to unlisten when the page exits: io.disconnect().

Listen for the intersecting area class

We can design a class that handles the logic of listening for intersecting areas.

The constructor

Let’s start with the constructor, which looks like this:

class IntersectionObserver {
  constructor(options) {
    this.$options = {
      context: null.threshold: 0.5.initialRatio: 0.observeAll: false.selector: null.relativeTo: null.onEach: res= > res.dataset,
      onFinal: (a)= > null.delay: 200. options, }this.$observer = null}}Copy the code

Obviously, the constructor to several important parameters, including createIntersectionObserver need three parameters: thresholds, initialRatio, observeAll context and context; Set the required relativeTo for the reference area. Listen for the target module selector required by the method.

Finally, there are three parameters required by the IntersectionObserver class to listen to the call:

  • OnEach: this is also called every time a listener call is triggeredonEachMethods;
  • OnFinal: the listener call is triggered for a period of timedelayAfter, it will be called onceonFinalMethods. In the module exposure buried point scenario, if the page is rapidly scrolling, each time the listening trigger will report the buried point, the time request will accumulate a lot, so it is requiredonFinalMethods: After a period of time, the exposure point was reported uniformly;
  • Delay: callonFinalMethod interval time;

Listening to the

To start listening to the intersection area, you need to create a listener first, and then start listening after setting the intersection area, the key code is as follows:

_createObserver() {
  const opt = this.$options
  const observerOptions = {
    thresholds: [opt.threshold],
    observeAll: opt.observeAll,
    initialRatio: opt.initialRatio,
  }

  // Create a listener
  const ob = opt.context
    ? opt.context.createIntersectionObserver(observerOptions)
    : wx.createIntersectionObserver(null, observerOptions)

  // Set the intersection locale
  if (opt.relativeTo) ob.relativeTo(opt.relativeTo)
  else ob.relativeToViewport()

  // Start listening
  let finalData = []
  let isCollecting = false   
  ob.observe(opt.selector, res => {
    const { intersectionRatio } = res
    const visible = intersectionRatio >= opt.threshold
    if(! visible)return

    const data = opt.onEach(res)
    finalData.push(data)

    if (isCollecting) return    // Collecting listening results, onFinal will not be called
    isCollecting = true    

    // Set the delay for calling onFinal
    setTimeout((a)= > {
      opt.onFinal.call(null, finalData)
      finalData = []
      isCollecting = false
    }, opt.delay)
  })
  return ob
}
Copy the code

A common method of exposure

Encapsulate the external _createObserver method:

connect() {
  if (this.$observer) return this
  this.$observer = this._createObserver()
  return this
}
Copy the code

Encapsulate the method to stop listening:

disconnect() {
  if(! this.$observer) return
  const ob = this.$observer
  if (ob.$timer) clearTimeout(ob.$timer)
  ob.disconnect()
  this.$observer = null
}
Copy the code

Method of use

import IntersectionObserver from './intersection-observer.js';

const ob = newIntersectionObserver({... }) ob.connect()Copy the code

See the code snippet: developers.weixin.qq.com/s/lqUakfmM7…

conclusion

Of course, exposure of buried points can also use the traditional Web listening for scroll events. However, since the applets provide IntersectionObserver API and almost all clients already support it, it is natural to use this more convenient approach.

In addition, baidu small program and Alipay small program also have related API support, cross-end development also need not consider other small program support.

About Compatibility

Pay package small application compatibility to textual research, baidu can use IntersectionObserver, but need to pay attention to this. CreateIntersectionObserver a component is not, Can only use swan. CreateIntersectionObserver (this); Second, the parameters of createIntersectionObserver observeAll need to selectAll (baidu small program code snippet: 142 c0f60156b1e850dc239553ecffe7b1571810456384 swanide: / / fragments).

Reference documentation

  1. Official documents;
  2. Discuss lazy loading of IntersectionObserver (details on Web API representation, same as in the mini program);