create-intersection-observer.js 1.7 KB
Newer Older
1
import Vue from 'vue'
2 3 4
import createCallbacks from 'uni-helpers/callbacks'

const createIntersectionObserverCallbacks = createCallbacks('requestComponentObserver')
5 6 7 8 9 10 11 12

const defaultOptions = {
  thresholds: [0],
  initialRatio: 0,
  observeAll: false
}

class MPIntersectionObserver {
13 14 15
  constructor (pageId, options) {
    this.pageId = pageId
    this.options = Object.assign({}, defaultOptions, options)
16 17
  }
  _makeRootMargin (margins = {}) {
18
    this.options.rootMargin = ['top', 'right', 'bottom', 'left'].map(name => `${Number(margins[name]) || 0}px`).join(' ')
19 20
  }
  relativeTo (selector, margins) {
21
    this.options.relativeToSelector = selector
22 23 24
    this._makeRootMargin(margins)
  }
  relativeToViewport (margins) {
25
    this.options.relativeToSelector = null
26 27 28 29 30 31
    this._makeRootMargin(margins)
  }
  observe (selector, callback) {
    if (typeof callback !== 'function') {
      return
    }
32 33 34 35 36 37 38 39
    this.options.selector = selector

    this.reqId = createIntersectionObserverCallbacks.push(callback)

    UniServiceJSBridge.publishHandler('requestComponentObserver', {
      reqId: this.reqId,
      options: this.options
    }, this.pageId)
40 41
  }
  disconnect () {
42 43 44
    UniServiceJSBridge.publishHandler('destroyComponentObserver', {
      reqId: this.reqId
    }, this.pageId)
45 46 47 48 49 50 51 52 53
  }
}

export function createIntersectionObserver (context, options) {
  if (!(context instanceof Vue)) {
    options = context
    context = null
  }
  if (context) {
54
    return new MPIntersectionObserver(context.$page.id, options)
55
  }
56 57 58
  const app = getApp()
  if (app.$route && app.$route.params.__id__) {
    return new MPIntersectionObserver(app.$route.params.__id__, options)
59 60 61 62
  } else {
    UniServiceJSBridge.emit('onError', 'createIntersectionObserver:fail')
  }
}