From 961b7475a337ca4ed346b81e06e176a3fc51ddcc Mon Sep 17 00:00:00 2001 From: wangcuijuan Date: Fri, 17 Apr 2026 12:20:40 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E5=8E=BB=E6=8E=89RN=E4=B8=8Bclears?= =?UTF-8?q?toragesync,=20=E4=BF=AE=E6=AD=A3off=E4=B8=8E=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=8B=89=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api-proxy/src/platform/api/app/index.web.js | 13 +++++++++++++ .../src/platform/api/device/network/rnNetwork.js | 2 +- .../api-proxy/src/platform/api/storage/rnStorage.js | 8 ++------ 3 files changed, 16 insertions(+), 7 deletions(-) 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..4955d48d92 100644 --- a/packages/api-proxy/src/platform/api/app/index.web.js +++ b/packages/api-proxy/src/platform/api/app/index.web.js @@ -34,6 +34,10 @@ function onError (callback) { } function offError (callback) { + if (callback == null) { + global.__mpxAppCbs.error.length = 0 + return + } off(global.__mpxAppCbs.error, callback) } @@ -44,16 +48,25 @@ function onAppShow (callback) { } function offAppShow (callback) { + if (callback == null) { + global.__mpxAppCbs.show.length = 0 + return + } off(global.__mpxAppCbs.show, callback) } function onAppHide (callback) { if (isBrowser || isReact) { + global.__mpxAppCbs.hide.push(callback) } } function offAppHide (callback) { + if (callback == null) { + global.__mpxAppCbs.hide.length = 0 + return + } off(global.__mpxAppCbs.hide, callback) } 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/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, From adae65682a3f7c248e9dac933215f3a6f219bb30 Mon Sep 17 00:00:00 2001 From: wangcuijuan Date: Wed, 22 Apr 2026 11:07:58 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E7=9B=98=E7=82=B9api=E6=9C=89?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E7=9A=84=E5=9C=B0=E6=96=B9=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/platform/api/app/index.web.js | 9 ++- .../src/platform/api/audio/index.web.js | 62 ++++++++++++++----- .../IntersectionObserver.js | 7 +-- .../device/network/onNetworkStatusChange.js | 12 ++++ .../src/platform/api/keyboard/index.ios.js | 8 +++ .../src/platform/api/location/index.web.js | 2 +- .../api/set-navigation-bar/index.web.js | 9 ++- .../src/platform/api/socket/SocketTask.js | 8 +-- .../src/platform/api/socket/index.web.js | 6 +- .../src/platform/api/system/index.ios.js | 4 +- .../src/platform/api/window/index.web.js | 5 ++ .../src/platform/api/window/rnWindow.js | 6 ++ 12 files changed, 104 insertions(+), 34 deletions(-) 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 4955d48d92..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) } @@ -57,7 +61,6 @@ function offAppShow (callback) { function onAppHide (callback) { if (isBrowser || isReact) { - global.__mpxAppCbs.hide.push(callback) } } @@ -78,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..5f791f3402 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,12 @@ export const createInnerAudioContext = () => { __audio.pause = () => audio.pause() + const _stopCbs = [] + __audio.stop = () => { __audio.pause() __audio.seek(0) + _stopCbs.forEach(cb => cb()) } __audio.seek = value => { @@ -49,27 +52,58 @@ export const createInnerAudioContext = () => { 'Seeking', 'TimeUpdate', 'Waiting', - 'Stop', 'Error' ] - const eventListeners = [ - ['on', audio.addEventListener], - ['off', audio.removeEventListener] - ] + + 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) => { + eventCallbacks[nativeName].push(cb) + audio.addEventListener(nativeName, cb) + } + } + }) + + Object.defineProperty(__audio, `off${eventName}`, { + get () { + return (cb) => { + if (cb == null) { + eventCallbacks[nativeName].forEach(fn => audio.removeEventListener(nativeName, fn)) + eventCallbacks[nativeName] = [] + } else { + const idx = eventCallbacks[nativeName].indexOf(cb) + if (idx > -1) { + eventCallbacks[nativeName].splice(idx, 1) + audio.removeEventListener(nativeName, cb) } - // 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..b9afefacf1 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._isInit = 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._isInit || (this._isInit && (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._isInit = 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/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/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) From 8432f8c897b8902ef318aaae44019276e08d334d Mon Sep 17 00:00:00 2001 From: wangcuijuan Date: Wed, 22 Apr 2026 19:45:11 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9isinit->isFirst?= =?UTF-8?q?=20=E4=BF=AE=E6=AD=A3=E9=9F=B3=E9=A2=91=E8=B0=83=E7=94=A8stop?= =?UTF-8?q?=E5=92=8Cpouse=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/platform/api/audio/index.web.js | 25 +++++++++++++------ .../IntersectionObserver.js | 6 ++--- 2 files changed, 20 insertions(+), 11 deletions(-) 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 5f791f3402..c8ca3b1f8b 100644 --- a/packages/api-proxy/src/platform/api/audio/index.web.js +++ b/packages/api-proxy/src/platform/api/audio/index.web.js @@ -15,9 +15,13 @@ export const createInnerAudioContext = () => { const _stopCbs = [] __audio.stop = () => { - __audio.pause() - __audio.seek(0) - _stopCbs.forEach(cb => cb()) + _stopping = true // 打开屏蔽开关,后续 pause 事件的 wrapper 会看到这个标志 + audio.pause() + audio.currentTime = 0 + setTimeout(() => { + _stopping = false // pause 事件已经派发完,关掉开关 + _stopCbs.forEach(cb => cb()) + }, 0) } __audio.seek = value => { @@ -55,6 +59,8 @@ export const createInnerAudioContext = () => { 'Error' ] + let _stopping = false + const eventCallbacks = {} eventNames.forEach(eventName => { const nativeName = eventName.toLowerCase() @@ -63,8 +69,11 @@ export const createInnerAudioContext = () => { Object.defineProperty(__audio, `on${eventName}`, { get () { return (cb) => { - eventCallbacks[nativeName].push(cb) - audio.addEventListener(nativeName, cb) + const wrapper = nativeName === 'pause' + ? (e) => { if (!_stopping) cb(e) } + : cb + eventCallbacks[nativeName].push({ cb, wrapper }) + audio.addEventListener(nativeName, wrapper) } } }) @@ -73,13 +82,13 @@ export const createInnerAudioContext = () => { get () { return (cb) => { if (cb == null) { - eventCallbacks[nativeName].forEach(fn => audio.removeEventListener(nativeName, fn)) + eventCallbacks[nativeName].forEach(({ wrapper }) => audio.removeEventListener(nativeName, wrapper)) eventCallbacks[nativeName] = [] } else { - const idx = eventCallbacks[nativeName].indexOf(cb) + const idx = eventCallbacks[nativeName].findIndex(item => item.cb === cb) if (idx > -1) { + audio.removeEventListener(nativeName, eventCallbacks[nativeName][idx].wrapper) eventCallbacks[nativeName].splice(idx, 1) - audio.removeEventListener(nativeName, cb) } } } 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 b9afefacf1..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 @@ -12,7 +12,7 @@ class WebIntersectionObserver { this._rootMargin = '' this._disconnected = false this._minThreshold = this.getMinThreshold() - this._isInit = true + this._isFirst = true } initObserver () { @@ -24,7 +24,7 @@ class WebIntersectionObserver { return new IntersectionObserver((entries, observer) => { const initialRatio = this._options.initialRatio || 0 entries.forEach(entry => { - if (!this._isInit || (this._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 () { @@ -56,7 +56,7 @@ class WebIntersectionObserver { this._callback && this._callback(entry) } }) - this._isInit = false + this._isFirst = false }, { root: this._root || null, rootMargin: this._rootMargin,