background

In the recent project, I developed a small program list page, and PM put forward a burying point requirement for me. When each item in the list appears on the screen, a record should be reported.

The target

How to do

My first instinct when I receive a request is, do I need to listen to the page scroll and use offsetTop to calculate it?! ????? This is obviously not the most efficient. Therefore, I checked the development documents of wechat and found an API of IntersectionObserver that just met my needs.

First of all, we need to create a IntersectionObserver wx. CreateIntersectionObserver (Object component, Object options)

IntersectionObserver has four methods

  1. IntersectionObserver.relativeToUse a selector to specify a node as one of the reference areas.
  2. IntersectionObserver.relativeToViewport(Object margins)Specify the page display area as one of the reference areas
  3. IntersectionObserver.observeCallback callback)Specify the target node and start listening for intersection state changes
  4. IntersectionObserver.disconnect()Stop listening. The callback function will no longer fire

We here is the reference of the screen, so we use IntersectionObserver. RelativeToViewport to make our reference, and formulate relative rules

Page({
  data: {
    list: [{value: 1.hadReport: false }, 
      { value: 2.hadReport: false },
      { value: 3.hadReport: false },
      { value: 4.hadReport: false },
      { value: 5.hadReport: false },
      { value: 6.hadReport: false },
      { value: 7.hadReport: false },
      { value: 8.hadReport: false },
      { value: 9.hadReport: false },
    ]
  },
  onLoad() {
    this._observer = this.createIntersectionObserver({ observeAll: true })
    this._observer.relativeToViewport({ bottom: 0 })
      .observe('.item', (res) => {
        const { index } = res.dataset;
        if (!this.data.list[index].hadReport) {
          console.log(`report ${index}`) 
          this.data.list[index].hadReport = true;
          this.setData({ list: [].concat(this.data.list)})
        }
        
      })
  },
  onUnload() {
    if (this._observer) this._observer.disconnect()
  }
})

Copy the code

The final result is as follows

conclusion

  1. Burying points like this can be done by listening to the DOM instead of just listening to the scrolling position.
  2. In addition to the buried point report, this way of monitoring, or very suitable to do some pictures lazy loading and a series of operations.

Wechat small program code snippets, click to view

lenovo

All of the above operations are based on wechat small program to do, so the browser has the corresponding API?

The browser has an API, the Intersection Observer API, that is similar in usage.

  var options = {
    rootMargin: '0px'.threshold: 1.0
  }

  var observer = new IntersectionObserver((. args) = > {
    console.log(args);
  }, options);
  observer.observe(document.querySelector('.item'));
Copy the code

Note that this monitors changes in the visibility of DOM elements, meaning that a callback is triggered when the DOM appears in the window and when it disappears in the window

However, browsers’ IntersectionObserver property is generally compatible. If you want to make exposure or lazy loading in the browser, you can consider using the original method to monitor browser scrolling and calculate dom offsetTop. You can refer to the principle and application of image delay loading written by the author a long time ago

Reference documentation

  • Talk about IntersectionObserver lazy loading
  • Wechat applet IntersectionObserver document