提交 65688b65 编写于 作者: fxy060608's avatar fxy060608

refactor(v3): createIntersectionObserver

上级 d223e34c
......@@ -7172,11 +7172,11 @@ var serviceContext = (function () {
const requestComponentInfoCallbacks = createCallbacks('requestComponentInfo');
function requestComponentInfo (pageInstance, queue, callback) {
function requestComponentInfo (pageVm, queue, callback) {
UniServiceJSBridge.publishHandler('requestComponentInfo', {
reqId: requestComponentInfoCallbacks.push(callback),
reqs: queue
}, pageInstance.$page.id);
}, pageVm.$page.id);
}
function parseDataset (attr) {
......@@ -7245,13 +7245,12 @@ var serviceContext = (function () {
});
}
function requestComponentInfo$1 (pageInstance, queue, callback) {
function requestComponentInfo$1 (pageVm, queue, callback) {
// TODO 重构,逻辑不对,queue 里的每一项可能有单独的作用域查找(即 component)
const vm = pageInstance.$vm;
const dom = vm._$weex.requireModule('dom');
const dom = pageVm._$weex.requireModule('dom');
const selectors = getSelectors(queue);
let outAttrs = new Array(selectors.length);
findAttrs(selectors, vm.$el, outAttrs);
findAttrs(selectors, pageVm.$el, outAttrs);
getComponentRectAll(dom, outAttrs, 0, [], (result) => {
callback(result);
});
......@@ -8608,6 +8607,76 @@ var serviceContext = (function () {
createAnimation: createAnimation
});
const createIntersectionObserverCallbacks = createCallbacks('requestComponentObserver');
const defaultOptions = {
thresholds: [0],
initialRatio: 0,
observeAll: false
};
class ServiceIntersectionObserver {
constructor (pageId, component, options) {
this.pageId = pageId;
this.component = component._$id || component; // app-plus 平台传输_$id
this.options = Object.assign({}, defaultOptions, options);
}
_makeRootMargin (margins = {}) {
this.options.rootMargin = ['top', 'right', 'bottom', 'left'].map(name => `${Number(margins[name]) || 0}px`).join(
' ');
}
relativeTo (selector, margins) {
this.options.relativeToSelector = selector;
this._makeRootMargin(margins);
return this
}
relativeToViewport (margins) {
this.options.relativeToSelector = null;
this._makeRootMargin(margins);
return this
}
observe (selector, callback) {
if (typeof callback !== 'function') {
return
}
this.options.selector = selector;
this.reqId = createIntersectionObserverCallbacks.push(callback);
UniServiceJSBridge.publishHandler('requestComponentObserver', {
reqId: this.reqId,
component: this.component,
options: this.options
}, this.pageId);
}
disconnect () {
UniServiceJSBridge.publishHandler('destroyComponentObserver', {
reqId: this.reqId
}, this.pageId);
}
}
function createIntersectionObserver (context, options) {
if (!context._isVue) {
options = context;
context = null;
}
if (context) {
return new ServiceIntersectionObserver(context.$page.id, context, options)
}
const pages = getCurrentPages();
const len = pages.length;
if (!len) {
UniServiceJSBridge.emit('onError', 'createIntersectionObserver:fail');
}
const page = pages[len - 1];
return new ServiceIntersectionObserver(page.$page.id, page.$vm, options)
}
var require_context_module_1_17 = /*#__PURE__*/Object.freeze({
createIntersectionObserver: createIntersectionObserver
});
class NodesRef {
constructor (selectorQuery, component, selector, single) {
this._selectorQuery = selectorQuery;
......@@ -8714,10 +8783,10 @@ var serviceContext = (function () {
if (!len) {
UniServiceJSBridge.emit('onError', 'createSelectorQuery:fail');
}
return new SelectorQuery(pages[len - 1])
return new SelectorQuery(pages[len - 1].$vm)
}
var require_context_module_1_17 = /*#__PURE__*/Object.freeze({
var require_context_module_1_18 = /*#__PURE__*/Object.freeze({
createSelectorQuery: createSelectorQuery
});
......@@ -8733,7 +8802,7 @@ var serviceContext = (function () {
callbacks$8.push(callbackId);
}
var require_context_module_1_18 = /*#__PURE__*/Object.freeze({
var require_context_module_1_19 = /*#__PURE__*/Object.freeze({
onKeyboardHeightChange: onKeyboardHeightChange
});
......@@ -8745,7 +8814,7 @@ var serviceContext = (function () {
return {}
}
var require_context_module_1_19 = /*#__PURE__*/Object.freeze({
var require_context_module_1_20 = /*#__PURE__*/Object.freeze({
pageScrollTo: pageScrollTo$1
});
......@@ -8781,7 +8850,7 @@ var serviceContext = (function () {
callbacks$9.push(callbackId);
}
var require_context_module_1_20 = /*#__PURE__*/Object.freeze({
var require_context_module_1_21 = /*#__PURE__*/Object.freeze({
removeTabBarBadge: removeTabBarBadge$1,
showTabBarRedDot: showTabBarRedDot$1,
hideTabBarRedDot: hideTabBarRedDot$1,
......@@ -8804,7 +8873,7 @@ var serviceContext = (function () {
callbacks$a.splice(callbacks$a.indexOf(callbackId), 1);
}
var require_context_module_1_21 = /*#__PURE__*/Object.freeze({
var require_context_module_1_22 = /*#__PURE__*/Object.freeze({
onWindowResize: onWindowResize,
offWindowResize: offWindowResize
});
......@@ -8831,11 +8900,12 @@ var serviceContext = (function () {
'./network/upload-file.js': require_context_module_1_14,
'./storage/storage.js': require_context_module_1_15,
'./ui/create-animation.js': require_context_module_1_16,
'./ui/create-selector-query.js': require_context_module_1_17,
'./ui/keyboard.js': require_context_module_1_18,
'./ui/page-scroll-to.js': require_context_module_1_19,
'./ui/tab-bar.js': require_context_module_1_20,
'./ui/window.js': require_context_module_1_21,
'./ui/create-intersection-observer.js': require_context_module_1_17,
'./ui/create-selector-query.js': require_context_module_1_18,
'./ui/keyboard.js': require_context_module_1_19,
'./ui/page-scroll-to.js': require_context_module_1_20,
'./ui/tab-bar.js': require_context_module_1_21,
'./ui/window.js': require_context_module_1_22,
};
var req = function req(key) {
......@@ -9819,6 +9889,12 @@ var serviceContext = (function () {
initData(Vue);
initLifecycle(Vue);
Object.defineProperty(Vue.prototype, '$page', {
get () {
return this.$root.$scope.$page
}
});
const oldMount = Vue.prototype.$mount;
Vue.prototype.$mount = function mount (el, hydrating) {
if (this.mpType === 'app') {
......
......@@ -21,7 +21,7 @@
"strip-json-comments": "^2.0.1"
},
"uni-app": {
"compilerVersion": "2.3.3"
"compilerVersion": "2.3.4"
},
"gitHead": "10184426b19cb76e01c93fb25c982c72887557e8"
}
import Vue from 'vue'
import createCallbacks from 'uni-helpers/callbacks'
const createIntersectionObserverCallbacks = createCallbacks('requestComponentObserver')
const defaultOptions = {
thresholds: [0],
initialRatio: 0,
observeAll: false
}
class MPIntersectionObserver {
constructor (pageId, options) {
this.pageId = pageId
this.options = Object.assign({}, defaultOptions, options)
}
_makeRootMargin (margins = {}) {
this.options.rootMargin = ['top', 'right', 'bottom', 'left'].map(name => `${Number(margins[name]) || 0}px`).join(' ')
}
relativeTo (selector, margins) {
this.options.relativeToSelector = selector
this._makeRootMargin(margins)
return this
}
relativeToViewport (margins) {
this.options.relativeToSelector = null
this._makeRootMargin(margins)
return this
}
observe (selector, callback) {
if (typeof callback !== 'function') {
return
}
this.options.selector = selector
this.reqId = createIntersectionObserverCallbacks.push(callback)
UniServiceJSBridge.publishHandler('requestComponentObserver', {
reqId: this.reqId,
options: this.options
}, this.pageId)
}
disconnect () {
UniServiceJSBridge.publishHandler('destroyComponentObserver', {
reqId: this.reqId
}, this.pageId)
}
}
export function createIntersectionObserver (context, options) {
if (!(context instanceof Vue)) {
options = context
context = null
}
if (context) {
return new MPIntersectionObserver(context.$page.id, options)
}
const app = getApp()
if (app.$route && app.$route.params.__id__) {
return new MPIntersectionObserver(app.$route.params.__id__, options)
} else {
UniServiceJSBridge.emit('onError', 'createIntersectionObserver:fail')
}
import createCallbacks from 'uni-helpers/callbacks'
const createIntersectionObserverCallbacks = createCallbacks('requestComponentObserver')
const defaultOptions = {
thresholds: [0],
initialRatio: 0,
observeAll: false
}
class ServiceIntersectionObserver {
constructor (pageId, component, options) {
this.pageId = pageId
this.component = component._$id || component // app-plus 平台传输_$id
this.options = Object.assign({}, defaultOptions, options)
}
_makeRootMargin (margins = {}) {
this.options.rootMargin = ['top', 'right', 'bottom', 'left'].map(name => `${Number(margins[name]) || 0}px`).join(
' ')
}
relativeTo (selector, margins) {
this.options.relativeToSelector = selector
this._makeRootMargin(margins)
return this
}
relativeToViewport (margins) {
this.options.relativeToSelector = null
this._makeRootMargin(margins)
return this
}
observe (selector, callback) {
if (typeof callback !== 'function') {
return
}
this.options.selector = selector
this.reqId = createIntersectionObserverCallbacks.push(callback)
UniServiceJSBridge.publishHandler('requestComponentObserver', {
reqId: this.reqId,
component: this.component,
options: this.options
}, this.pageId)
}
disconnect () {
UniServiceJSBridge.publishHandler('destroyComponentObserver', {
reqId: this.reqId
}, this.pageId)
}
}
export function createIntersectionObserver (context, options) {
if (!context._isVue) {
options = context
context = null
}
if (context) {
return new ServiceIntersectionObserver(context.$page.id, context, options)
}
const pages = getCurrentPages()
const len = pages.length
if (!len) {
UniServiceJSBridge.emit('onError', 'createIntersectionObserver:fail')
}
const page = pages[len - 1]
return new ServiceIntersectionObserver(page.$page.id, page.$vm, options)
}
......@@ -111,5 +111,5 @@ export function createSelectorQuery (context) {
if (!len) {
UniServiceJSBridge.emit('onError', 'createSelectorQuery:fail')
}
return new SelectorQuery(pages[len - 1])
return new SelectorQuery(pages[len - 1].$vm)
}
......@@ -4,6 +4,10 @@ import {
import getWindowOffset from 'uni-platform/helpers/get-window-offset'
import {
findElm
} from './util'
function getRootInfo (fields) {
const info = {}
if (fields.id) {
......@@ -73,38 +77,8 @@ function getNodeInfo (el, fields) {
return info
}
function findElm (id, vm) {
if (id === vm._$id) {
return vm
}
const childVms = vm.$children
const len = childVms.length
for (let i = 0; i < len; i++) {
const childVm = findElm(id, childVms[i])
if (childVm) {
return childVm
}
}
}
function getElm (component, pageVm) {
if (!component) {
return pageVm.$el
}
if (__PLATFORM__ === 'app-plus') {
if (typeof component === 'string') {
const componentVm = findElm(component, pageVm)
if (!componentVm) {
throw new Error(`Not Found:Page[${pageVm.$page.id}][${component}]`)
}
return componentVm.$el
}
}
return component.$el
}
function getNodesInfo (pageVm, component, selector, single, fields) {
const $el = getElm(component, pageVm)
const $el = findElm(component, pageVm)
if (single) {
const node = $el && ($el.matches(selector) ? $el : $el.querySelector(selector))
if (node) {
......
import 'intersection-observer'
import {
normalizeDataset
} from 'uni-helpers/index'
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}]`)
import 'intersection-observer'
import {
normalizeDataset
} from 'uni-helpers/index'
import {
findElm
} from './util'
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,
component,
options
}, pageId) {
const pages = getCurrentPages()
const page = pages.find(page => page.$page.id === pageId)
if (!page) {
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
})
}
const pageVm = page.$vm
const $el = findElm(component, pageVm)
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
})
}
}
function findVmById (id, vm) {
if (id === vm._$id) {
return vm
}
const childVms = vm.$children
const len = childVms.length
for (let i = 0; i < len; i++) {
const childVm = findVmById(id, childVms[i])
if (childVm) {
return childVm
}
}
}
export function findElm (component, pageVm) {
if (!component) {
return pageVm.$el
}
if (__PLATFORM__ === 'app-plus') {
if (typeof component === 'string') {
const componentVm = findVmById(component, pageVm)
if (!componentVm) {
throw new Error(`Not Found:Page[${pageVm.$page.id}][${component}]`)
}
return componentVm.$el
}
}
return component.$el
}
......@@ -64,13 +64,12 @@ function getComponentRectAll (dom, attrs, index, result, callback) {
})
}
export function requestComponentInfo (pageInstance, queue, callback) {
export function requestComponentInfo (pageVm, queue, callback) {
// TODO 重构,逻辑不对,queue 里的每一项可能有单独的作用域查找(即 component)
const vm = pageInstance.$vm
const dom = vm._$weex.requireModule('dom')
const dom = pageVm._$weex.requireModule('dom')
const selectors = getSelectors(queue)
let outAttrs = new Array(selectors.length)
findAttrs(selectors, vm.$el, outAttrs)
findAttrs(selectors, pageVm.$el, outAttrs)
getComponentRectAll(dom, outAttrs, 0, [], (result) => {
callback(result)
})
......
......@@ -19,6 +19,12 @@ export default {
initData(Vue)
initLifecycle(Vue)
Object.defineProperty(Vue.prototype, '$page', {
get () {
return this.$root.$scope.$page
}
})
const oldMount = Vue.prototype.$mount
Vue.prototype.$mount = function mount (el, hydrating) {
if (this.mpType === 'app') {
......
......@@ -2,9 +2,9 @@ import createCallbacks from 'uni-helpers/callbacks'
const requestComponentInfoCallbacks = createCallbacks('requestComponentInfo')
export function requestComponentInfo (pageInstance, queue, callback) {
export function requestComponentInfo (pageVm, queue, callback) {
UniServiceJSBridge.publishHandler('requestComponentInfo', {
reqId: requestComponentInfoCallbacks.push(callback),
reqs: queue
}, pageInstance.$page.id)
}, pageVm.$page.id)
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册