diff --git a/packages/api-proxy/src/platform/api/app/index.web.js b/packages/api-proxy/src/platform/api/app/index.web.js index 7feb4c345c..3e3ee675f5 100644 --- a/packages/api-proxy/src/platform/api/app/index.web.js +++ b/packages/api-proxy/src/platform/api/app/index.web.js @@ -24,6 +24,10 @@ function onUnhandledRejection (callback) { } function offUnhandledRejection (callback) { + if (callback == null) { + global.__mpxAppCbs.rejection.length = 0 + return + } off(global.__mpxAppCbs.rejection, callback) } @@ -34,6 +38,10 @@ function onError (callback) { } function offError (callback) { + if (callback == null) { + global.__mpxAppCbs.error.length = 0 + return + } off(global.__mpxAppCbs.error, callback) } @@ -44,6 +52,10 @@ function onAppShow (callback) { } function offAppShow (callback) { + if (callback == null) { + global.__mpxAppCbs.show.length = 0 + return + } off(global.__mpxAppCbs.show, callback) } @@ -54,6 +66,10 @@ function onAppHide (callback) { } function offAppHide (callback) { + if (callback == null) { + global.__mpxAppCbs.hide.length = 0 + return + } off(global.__mpxAppCbs.hide, callback) } @@ -65,6 +81,10 @@ function onLazyLoadError (callback) { function offLazyLoadError (callback) { if (isReact) { + if (callback == null) { + global.__mpxAppCbs.lazyLoad.length = 0 + return + } off(global.__mpxAppCbs.lazyLoad, callback) } } diff --git a/packages/api-proxy/src/platform/api/audio/index.web.js b/packages/api-proxy/src/platform/api/audio/index.web.js index d8c1a853b0..c8ca3b1f8b 100644 --- a/packages/api-proxy/src/platform/api/audio/index.web.js +++ b/packages/api-proxy/src/platform/api/audio/index.web.js @@ -12,9 +12,16 @@ export const createInnerAudioContext = () => { __audio.pause = () => audio.pause() + const _stopCbs = [] + __audio.stop = () => { - __audio.pause() - __audio.seek(0) + _stopping = true // 打开屏蔽开关,后续 pause 事件的 wrapper 会看到这个标志 + audio.pause() + audio.currentTime = 0 + setTimeout(() => { + _stopping = false // pause 事件已经派发完,关掉开关 + _stopCbs.forEach(cb => cb()) + }, 0) } __audio.seek = value => { @@ -49,27 +56,63 @@ export const createInnerAudioContext = () => { 'Seeking', 'TimeUpdate', 'Waiting', - 'Stop', 'Error' ] - const eventListeners = [ - ['on', audio.addEventListener], - ['off', audio.removeEventListener] - ] + + let _stopping = false + + const eventCallbacks = {} eventNames.forEach(eventName => { - eventListeners.forEach(([eventNameItem, listenerFn]) => { - Object.defineProperty(__audio, `${eventNameItem}${eventName}`, { - get () { - return (callback = audio.cb) => { - if (eventNameItem !== 'off') { - audio.cb = callback + const nativeName = eventName.toLowerCase() + eventCallbacks[nativeName] = [] + + Object.defineProperty(__audio, `on${eventName}`, { + get () { + return (cb) => { + const wrapper = nativeName === 'pause' + ? (e) => { if (!_stopping) cb(e) } + : cb + eventCallbacks[nativeName].push({ cb, wrapper }) + audio.addEventListener(nativeName, wrapper) + } + } + }) + + Object.defineProperty(__audio, `off${eventName}`, { + get () { + return (cb) => { + if (cb == null) { + eventCallbacks[nativeName].forEach(({ wrapper }) => audio.removeEventListener(nativeName, wrapper)) + eventCallbacks[nativeName] = [] + } else { + const idx = eventCallbacks[nativeName].findIndex(item => item.cb === cb) + if (idx > -1) { + audio.removeEventListener(nativeName, eventCallbacks[nativeName][idx].wrapper) + eventCallbacks[nativeName].splice(idx, 1) } - // debugger - return listenerFn.call(audio, eventName.toLowerCase(), audio.cb) } } - }) + } }) }) + + Object.defineProperty(__audio, 'onStop', { + get () { + return (cb) => { _stopCbs.push(cb) } + } + }) + Object.defineProperty(__audio, 'offStop', { + get () { + return (cb) => { + if (cb == null) { + _stopCbs.length = 0 + } else { + const idx = _stopCbs.indexOf(cb) + if (idx > -1) _stopCbs.splice(idx, 1) + } + } + } + }) + return __audio } diff --git a/packages/api-proxy/src/platform/api/create-intersection-observer/IntersectionObserver.js b/packages/api-proxy/src/platform/api/create-intersection-observer/IntersectionObserver.js index b7c880ab07..56f8ffaaa9 100644 --- a/packages/api-proxy/src/platform/api/create-intersection-observer/IntersectionObserver.js +++ b/packages/api-proxy/src/platform/api/create-intersection-observer/IntersectionObserver.js @@ -1,8 +1,6 @@ import { nextTick } from '../next-tick' import { parseDataset, warn } from '@mpxjs/utils' -let isInit = true - class WebIntersectionObserver { constructor (_component, options) { this._component = _component @@ -14,6 +12,7 @@ class WebIntersectionObserver { this._rootMargin = '' this._disconnected = false this._minThreshold = this.getMinThreshold() + this._isFirst = true } initObserver () { @@ -25,7 +24,7 @@ class WebIntersectionObserver { return new IntersectionObserver((entries, observer) => { const initialRatio = this._options.initialRatio || 0 entries.forEach(entry => { - if (!isInit || (isInit && (entry.intersectionRatio !== initialRatio && (this._minThreshold <= entry.intersectionRatio)))) { + if (!this._isFirst || (this._isFirst && (entry.intersectionRatio !== initialRatio && (this._minThreshold <= entry.intersectionRatio)))) { Object.defineProperties(entry, { id: { get () { @@ -57,7 +56,7 @@ class WebIntersectionObserver { this._callback && this._callback(entry) } }) - isInit = false + this._isFirst = false }, { root: this._root || null, rootMargin: this._rootMargin, diff --git a/packages/api-proxy/src/platform/api/device/network/onNetworkStatusChange.js b/packages/api-proxy/src/platform/api/device/network/onNetworkStatusChange.js index 36623d9eb9..e77178cfd6 100644 --- a/packages/api-proxy/src/platform/api/device/network/onNetworkStatusChange.js +++ b/packages/api-proxy/src/platform/api/device/network/onNetworkStatusChange.js @@ -37,8 +37,20 @@ export function offNetworkStatusChange (callbackFn) { throwSSRWarning('offNetworkStatusChange API is running in non browser environments') return } + if (callbackFn == null) { + // 不传 callback 时清除所有监听 + fnMap.forEach((proxyCallback, originalCallback) => { + if (navigator.connection) { + navigator.connection.removeEventListener('change', proxyCallback) + } + }) + fnMap.clear() + oldObserveList.clear() + return + } if (navigator.connection) { navigator.connection.removeEventListener('change', fnMap.get(callbackFn)) + fnMap.delete(callbackFn) } else { oldObserveList.has(callbackFn) && oldObserveList.delete(callbackFn) } diff --git a/packages/api-proxy/src/platform/api/device/network/rnNetwork.js b/packages/api-proxy/src/platform/api/device/network/rnNetwork.js index 96617bd69a..434b456e50 100644 --- a/packages/api-proxy/src/platform/api/device/network/rnNetwork.js +++ b/packages/api-proxy/src/platform/api/device/network/rnNetwork.js @@ -45,7 +45,7 @@ const onNetworkStatusChange = function (callback) { const offNetworkStatusChange = function (callback) { if (callback && typeof callback === 'function') { _callbacks.delete(callback) - } else if (callback === undefined) { + } else if (callback == null) { _callbacks.clear() _unsubscribe && _unsubscribe() _unsubscribe = null diff --git a/packages/api-proxy/src/platform/api/keyboard/index.ios.js b/packages/api-proxy/src/platform/api/keyboard/index.ios.js index 611eb03292..75e0c8d115 100644 --- a/packages/api-proxy/src/platform/api/keyboard/index.ios.js +++ b/packages/api-proxy/src/platform/api/keyboard/index.ios.js @@ -32,6 +32,14 @@ const onKeyboardHeightChange = function (callback) { callbacks.push(callback) } const offKeyboardHeightChange = function (callback) { + if (callback == null) { + // 不传 callback 时清除所有监听 + callbacks.length = 0 + Keyboard.removeAllListeners('keyboardDidShow') + Keyboard.removeAllListeners('keyboardDidHide') + hasListener = false + return + } const index = callbacks.indexOf(callback) if (index > -1) { callbacks.splice(index, 1) diff --git a/packages/api-proxy/src/platform/api/location/index.web.js b/packages/api-proxy/src/platform/api/location/index.web.js index 23fe942abc..306117a812 100644 --- a/packages/api-proxy/src/platform/api/location/index.web.js +++ b/packages/api-proxy/src/platform/api/location/index.web.js @@ -10,7 +10,7 @@ const getLocation = function (options = {}) { errMsg: 'getLocation:ok', latitude: coords.latitude, longitude: coords.longitude, - speed: coords.accuracy + speed: coords.speed } defineUnsupportedProps(result, ['horizontalAccuracy', 'verticalAccuracy']) successHandle(result, success, complete) diff --git a/packages/api-proxy/src/platform/api/set-navigation-bar/index.web.js b/packages/api-proxy/src/platform/api/set-navigation-bar/index.web.js index 198ac4b945..43d7a1b7c3 100644 --- a/packages/api-proxy/src/platform/api/set-navigation-bar/index.web.js +++ b/packages/api-proxy/src/platform/api/set-navigation-bar/index.web.js @@ -19,10 +19,13 @@ function setNavigationBarColor (options = {}) { return } const { backgroundColor, success, complete } = options - const meta = document.createElement('meta') - meta.setAttribute('name', 'theme-color') + let meta = document.querySelector('meta[name="theme-color"]') + if (!meta) { + meta = document.createElement('meta') + meta.setAttribute('name', 'theme-color') + document.head.appendChild(meta) + } meta.setAttribute('content', backgroundColor) - document.head.appendChild(meta) successHandle({ errMsg: 'setNavigationBarColor:ok' }, success, complete) } diff --git a/packages/api-proxy/src/platform/api/socket/SocketTask.js b/packages/api-proxy/src/platform/api/socket/SocketTask.js index fa6cb517ae..d27185339e 100644 --- a/packages/api-proxy/src/platform/api/socket/SocketTask.js +++ b/packages/api-proxy/src/platform/api/socket/SocketTask.js @@ -12,9 +12,9 @@ class SocketTask { this._closeData = null if (protocols && protocols.length > 0) { - this._socket = new window.WebSocket(url, protocols) + this._socket = new WebSocket(url, protocols) } else { - this._socket = new window.WebSocket(url) + this._socket = new WebSocket(url) } this.addListener(this._socket) socketTasks.add(this._socket) @@ -62,7 +62,7 @@ class SocketTask { reason } try { - this._socket.close() + this._socket.close(code, reason) const res = { errMsg: 'closeSocket:ok' } successHandle(res, success, complete) } catch (err) { @@ -90,7 +90,7 @@ class SocketTask { return } if (this._closeData) { - this._closeCb(event) + this._closeCb(this._closeData) } else { this._closeCb({ code: event.code, reason: event.reason }) } diff --git a/packages/api-proxy/src/platform/api/socket/index.web.js b/packages/api-proxy/src/platform/api/socket/index.web.js index 3b5137affe..e16f5a7f14 100644 --- a/packages/api-proxy/src/platform/api/socket/index.web.js +++ b/packages/api-proxy/src/platform/api/socket/index.web.js @@ -1,11 +1,7 @@ -import { warn, successHandle, failHandle, isBrowser, throwSSRWarning } from '../../../common/js' +import { warn, successHandle, failHandle } from '../../../common/js' import SocketTask from './SocketTask' function connectSocket (options = { url: '' }) { - if (!isBrowser) { - throwSSRWarning('connectSocket API is running in non browser environments') - return - } const { url, protocols, success, fail, complete } = options try { diff --git a/packages/api-proxy/src/platform/api/storage/rnStorage.js b/packages/api-proxy/src/platform/api/storage/rnStorage.js index 8612c44813..213b7afaab 100644 --- a/packages/api-proxy/src/platform/api/storage/rnStorage.js +++ b/packages/api-proxy/src/platform/api/storage/rnStorage.js @@ -100,9 +100,7 @@ function removeStorage (options = {}) { }) } -function removeStorageSync (key) { - AsyncStorage.removeItem(key) -} +const removeStorageSync = envError('removeStorageSync') function clearStorage (options = {}) { const { success, fail, complete } = options @@ -121,9 +119,7 @@ function clearStorage (options = {}) { }) } -function clearStorageSync () { - AsyncStorage.clear() -} +const clearStorageSync = envError('clearStorageSync') export { setStorage, diff --git a/packages/api-proxy/src/platform/api/system/index.ios.js b/packages/api-proxy/src/platform/api/system/index.ios.js index 18cf06973d..c3c1cdebfd 100644 --- a/packages/api-proxy/src/platform/api/system/index.ios.js +++ b/packages/api-proxy/src/platform/api/system/index.ios.js @@ -12,7 +12,7 @@ const getSystemInfoSync = function () { model: DeviceInfo.getModel(), system: `${DeviceInfo.getSystemName()} ${DeviceInfo.getSystemVersion()}`, platform: DeviceInfo.isEmulatorSync() ? 'emulator' : DeviceInfo.getSystemName().toLowerCase(), - deviceOrientation: screenWidth > screenHeight ? 'portrait' : 'landscape', + deviceOrientation: screenWidth > screenHeight ? 'landscape' : 'portrait', fontSizeSetting: PixelRatio.getFontScale() } Object.assign(result, windowInfo) @@ -46,7 +46,7 @@ const getSystemInfo = function (options = {}) { try { const systemInfo = getSystemInfoSync() Object.assign(systemInfo, { - errMsg: 'setStorage:ok' + errMsg: 'getSystemInfo:ok' }) successHandle(systemInfo, success, complete) } catch (err) { diff --git a/packages/api-proxy/src/platform/api/window/index.web.js b/packages/api-proxy/src/platform/api/window/index.web.js index b85f0c13c8..5cae440309 100644 --- a/packages/api-proxy/src/platform/api/window/index.web.js +++ b/packages/api-proxy/src/platform/api/window/index.web.js @@ -19,6 +19,11 @@ function onWindowResize (callback) { } function offWindowResize (callback) { + if (callback == null) { + // 不传 callback 时清除所有监听 + callbacks.length = 0 + return + } const index = callbacks.indexOf(callback) if (index > -1) { callbacks.splice(index, 1) diff --git a/packages/api-proxy/src/platform/api/window/rnWindow.js b/packages/api-proxy/src/platform/api/window/rnWindow.js index 026d127777..6cc638485e 100644 --- a/packages/api-proxy/src/platform/api/window/rnWindow.js +++ b/packages/api-proxy/src/platform/api/window/rnWindow.js @@ -29,6 +29,12 @@ function onWindowResize (callback) { } function offWindowResize (callback) { + if (callback == null) { + // 不传 callback 时清除所有监听 + callbacks.length = 0 + removeListener() + return + } const index = callbacks.indexOf(callback) if (index > -1) { callbacks.splice(index, 1)