提交 84887cae 编写于 作者: Q qiang

update: uni.createIntersectionObserver 接口改为在 view 层处理

上级 edc7b710
import Vue from 'vue' import Vue from 'vue'
import 'intersection-observer' import createCallbacks from 'uni-helpers/callbacks'
const createIntersectionObserverCallbacks = createCallbacks('requestComponentObserver')
const defaultOptions = { const defaultOptions = {
thresholds: [0], thresholds: [0],
...@@ -8,60 +10,38 @@ const defaultOptions = { ...@@ -8,60 +10,38 @@ const defaultOptions = {
} }
class MPIntersectionObserver { class MPIntersectionObserver {
_intersectionObserver constructor (pageId, options) {
_el this.pageId = pageId
_options this.options = Object.assign({}, defaultOptions, options)
_root = null
_rootMargin = '0'
constructor (context, options) {
this._el = context.$el
this._options = Object.assign({}, defaultOptions, options)
} }
_makeRootMargin (margins = {}) { _makeRootMargin (margins = {}) {
this._rootMargin = ['top', 'right', 'bottom', 'left'].map(name => `${Number(margins[name]) || 0}px`).join(' ') this.options.rootMargin = ['top', 'right', 'bottom', 'left'].map(name => `${Number(margins[name]) || 0}px`).join(' ')
} }
relativeTo (selector, margins) { relativeTo (selector, margins) {
this._root = this._el.querySelector(selector) this.options.relativeToSelector = selector
this._makeRootMargin(margins) this._makeRootMargin(margins)
} }
relativeToViewport (margins) { relativeToViewport (margins) {
this._root = null this.options.relativeToSelector = null
this._makeRootMargin(margins) this._makeRootMargin(margins)
} }
observe (selector, callback) { observe (selector, callback) {
if (typeof callback !== 'function') { if (typeof callback !== 'function') {
return return
} }
let options = { this.options.selector = selector
root: this._root,
rootMargin: this._rootMargin, this.reqId = createIntersectionObserverCallbacks.push(callback)
threshold: this._options.thresholds
} UniServiceJSBridge.publishHandler('requestComponentObserver', {
let intersectionObserver = this._intersectionObserver = new IntersectionObserver((entries, observer) => { reqId: this.reqId,
entries.forEach(entrie => { options: this.options
callback({ }, this.pageId)
intersectionRatio: entrie.intersectionRatio,
intersectionRect: entrie.intersectionRect,
boundingClientRect: entrie.boundingClientRect,
relativeRect: entrie.rootBounds,
time: entrie.time,
dataset: entrie.target.dataset,
id: entrie.target.id
})
})
}, options)
if (this._options.observeAll) {
intersectionObserver.USE_MUTATION_OBSERVER = true
Array.prototype.map.call(this._el.querySelectorAll(selector), el => {
intersectionObserver.observe(el)
})
} else {
intersectionObserver.USE_MUTATION_OBSERVER = false
intersectionObserver.observe(this._el.querySelector(selector))
}
} }
disconnect () { disconnect () {
this._intersectionObserver && this._intersectionObserver.disconnect() UniServiceJSBridge.publishHandler('destroyComponentObserver', {
reqId: this.reqId
}, this.pageId)
} }
} }
...@@ -71,12 +51,11 @@ export function createIntersectionObserver (context, options) { ...@@ -71,12 +51,11 @@ export function createIntersectionObserver (context, options) {
context = null context = null
} }
if (context) { if (context) {
return new MPIntersectionObserver(context, options) return new MPIntersectionObserver(context.$page.id, options)
} }
const pages = getCurrentPages() const app = getApp()
if (pages.length) { if (app.$route && app.$route.params.__id__) {
context = pages[pages.length - 1] return new MPIntersectionObserver(app.$route.params.__id__, options)
return new MPIntersectionObserver(context, options)
} else { } else {
UniServiceJSBridge.emit('onError', 'createIntersectionObserver:fail') UniServiceJSBridge.emit('onError', 'createIntersectionObserver:fail')
} }
......
...@@ -39,6 +39,7 @@ function onRequestComponentObserver ({ ...@@ -39,6 +39,7 @@ function onRequestComponentObserver ({
if (callback) { if (callback) {
if (reqEnd) { if (reqEnd) {
requestComponentObserverCallbacks.pop(reqId) requestComponentObserverCallbacks.pop(reqId)
return
} }
callback(res) callback(res)
} }
...@@ -51,4 +52,4 @@ export default function initSubscribe (subscribe) { ...@@ -51,4 +52,4 @@ export default function initSubscribe (subscribe) {
subscribe('onRequestComponentInfo', onRequestComponentInfo) subscribe('onRequestComponentInfo', onRequestComponentInfo)
subscribe('onRequestComponentObserver', onRequestComponentObserver) subscribe('onRequestComponentObserver', onRequestComponentObserver)
} }
...@@ -17,6 +17,8 @@ import { ...@@ -17,6 +17,8 @@ import {
import requestComponentInfo from './request-component-info' import requestComponentInfo from './request-component-info'
import { requestComponentObserver, destroyComponentObserver } from './request-component-observer'
const passiveOptions = supportsPassive ? { const passiveOptions = supportsPassive ? {
passive: false passive: false
} : false } : false
...@@ -40,6 +42,9 @@ export default function initSubscribe (subscribe) { ...@@ -40,6 +42,9 @@ export default function initSubscribe (subscribe) {
subscribe('pageScrollTo', pageScrollTo) subscribe('pageScrollTo', pageScrollTo)
subscribe('requestComponentObserver', requestComponentObserver)
subscribe('destroyComponentObserver', destroyComponentObserver)
if (__PLATFORM__ === 'h5') { if (__PLATFORM__ === 'h5') {
let scrollListener = false let scrollListener = false
let disableScrollListener = false let disableScrollListener = false
...@@ -48,7 +53,7 @@ export default function initSubscribe (subscribe) { ...@@ -48,7 +53,7 @@ export default function initSubscribe (subscribe) {
updateCssVar(vm) updateCssVar(vm)
}) })
subscribe('onPageShow', vm => { subscribe('onPageShow', vm => {
const pageVm = vm.$parent.$parent const pageVm = vm.$parent.$parent
if (vm._isMounted) { // 非首次 show 才 update(首次 show 的时候在 onPageLoad 中触发了) if (vm._isMounted) { // 非首次 show 才 update(首次 show 的时候在 onPageLoad 中触发了)
...@@ -87,4 +92,4 @@ export default function initSubscribe (subscribe) { ...@@ -87,4 +92,4 @@ export default function initSubscribe (subscribe) {
} }
}) })
} }
} }
import 'intersection-observer'
import {
normalizeDataset
} from 'uni-helpers'
function getRect (rect) {
return {
bottom: rect.bottom,
height: rect.height,
left: rect.left,
right: rect.right,
top: rect.top,
width: rect.width
}
}
const intersectionObservers = {}
export function requestComponentObserver ({
reqId,
options
}, pageId) {
const pages = getCurrentPages()
const pageVm = pages.find(page => page.$page.id === pageId)
if (!pageVm) {
throw new Error(`Not Found:Page[${pageId}]`)
}
const $el = pageVm.$el
const root = options.relativeToSelector ? $el.querySelector(options.relativeToSelector) : null
let intersectionObserver = intersectionObservers[reqId] = new IntersectionObserver((entries, observer) => {
entries.forEach(entrie => {
UniViewJSBridge.publishHandler('onRequestComponentObserver', {
reqId,
res: {
intersectionRatio: entrie.intersectionRatio,
intersectionRect: getRect(entrie.intersectionRect),
boundingClientRect: getRect(entrie.boundingClientRect),
relativeRect: getRect(entrie.rootBounds),
time: Date.now(),
dataset: normalizeDataset(entrie.target.dataset || {}),
id: entrie.target.id
}
}, pageVm.$page.id)
})
}, {
root,
rootMargin: options.rootMargin,
threshold: options.thresholds
})
if (options.observeAll) {
intersectionObserver.USE_MUTATION_OBSERVER = true
Array.prototype.map.call($el.querySelectorAll(options.selector), el => {
intersectionObserver.observe(el)
})
} else {
intersectionObserver.USE_MUTATION_OBSERVER = false
intersectionObserver.observe($el.querySelector(options.selector))
}
}
export function destroyComponentObserver ({ reqId }) {
const intersectionObserver = intersectionObservers[reqId]
if (intersectionObserver) {
intersectionObserver.disconnect()
UniViewJSBridge.publishHandler('onRequestComponentObserver', {
reqId,
reqEnd: true
})
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册