From 39584b90db2c5c7789ade468905ecb493d346dbe Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Thu, 27 Aug 2026 01:43:27 +0800 Subject: [PATCH 1/7] fix(swipe): guard document.addEventListener in Taro env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在 Taro Android/iOS 运行时 document.addEventListener 可能不是函数, 在调用前增加环境检测,避免抛出 not a function 错误。 Co-Authored-By: Claude --- src/packages/swipe/swipe.taro.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/packages/swipe/swipe.taro.tsx b/src/packages/swipe/swipe.taro.tsx index 711dee5e1a..caae5134bc 100644 --- a/src/packages/swipe/swipe.taro.tsx +++ b/src/packages/swipe/swipe.taro.tsx @@ -231,6 +231,11 @@ export const Swipe = forwardRef< })) useEffect(() => { + if ( + typeof document === 'undefined' || + typeof document.addEventListener !== 'function' + ) + return // 并没有生效 const handler: any = (event: { target: Node | null }) => { const targets = [root] From 12a451d241dfea427b040017e935c8f2e6b7b1f4 Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Thu, 27 Aug 2026 01:58:33 +0800 Subject: [PATCH 2/7] fix(taro): guard document API calls in non-H5 environments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit imagepreview/barrage/popover 在 Taro Android/iOS 运行时直接访问 document API 会抛出 not a function,补充 typeof 守卫与 swipe 保持一致。 Co-Authored-By: Claude --- src/packages/barrage/barrage.taro.tsx | 5 +++++ src/packages/imagepreview/imagepreview.taro.tsx | 5 +++++ src/packages/popover/popover.taro.tsx | 4 +++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/packages/barrage/barrage.taro.tsx b/src/packages/barrage/barrage.taro.tsx index f5e2e6c254..7851a5b3e1 100644 --- a/src/packages/barrage/barrage.taro.tsx +++ b/src/packages/barrage/barrage.taro.tsx @@ -144,6 +144,11 @@ const InternalBarrage: ForwardRefRenderFunction< if (!loop && index.current >= list.length) { return } + if ( + typeof document === 'undefined' || + typeof document.createElement !== 'function' + ) + return const _index = loop ? index.current % list.length : index.current const el = document.createElement(`View`) diff --git a/src/packages/imagepreview/imagepreview.taro.tsx b/src/packages/imagepreview/imagepreview.taro.tsx index 4cbba5e8ad..ae43708bcf 100644 --- a/src/packages/imagepreview/imagepreview.taro.tsx +++ b/src/packages/imagepreview/imagepreview.taro.tsx @@ -149,6 +149,11 @@ export const ImagePreview: FunctionComponent> = ( init() }, []) const init = () => { + if ( + typeof document === 'undefined' || + typeof document.addEventListener !== 'function' + ) + return document.addEventListener('touchmove', onTouchMove as any) document.addEventListener('touchend', onTouchEnd) document.addEventListener('touchcancel', onTouchEnd) diff --git a/src/packages/popover/popover.taro.tsx b/src/packages/popover/popover.taro.tsx index 51c0f83b18..68283bd413 100644 --- a/src/packages/popover/popover.taro.tsx +++ b/src/packages/popover/popover.taro.tsx @@ -86,7 +86,9 @@ export const Popover: FunctionComponent< nextTick(async () => { const rect = targetId ? await getRectInMultiPlatform( - document.querySelector(`#${targetId}`), + typeof document !== 'undefined' + ? document.querySelector(`#${targetId}`) + : null, targetId ) : await getRectInMultiPlatform(popoverRef.current, popoverId) From ccd5b75a8efd3f3240fe14bdfffe11077b4bea63 Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Fri, 28 Aug 2026 22:41:24 +0800 Subject: [PATCH 3/7] test: add document guard unit tests for swipe/imagepreview/barrage taro components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 验证 Taro 非 H5 环境下 document API 不可用时 guard 条件表达式行为正确, 同步更新 CHANGELOG 并升级版本至 v3.0.22-cpp。 Co-Authored-By: Claude --- CHANGELOG.md | 7 ++++++ package.json | 2 +- .../barrage/__tests__/barrage.spec.tsx | 22 ++++++++++++++++ .../__test__/imagepreview.spec.tsx | 22 ++++++++++++++++ src/packages/swipe/__tests__/swipe.spec.tsx | 25 +++++++++++++++++++ 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9074220e8..54cbace165 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v3.0.22-cpp + +`2026-08-28` + +- 🐛 fix(swipe): 修复 Taro Android/iOS 环境下 `document.addEventListener` 不是函数导致报错的问题 +- 🐛 fix(taro): 修复 imagepreview/barrage/popover 在 Taro 非 H5 环境下访问 `document` API 报错的问题 + # v3.0.21-cpp `2026-05-20` diff --git a/package.json b/package.json index 058a4356fa..db1d8d969b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nutui/nutui-react-taro", - "version": "3.0.21-cpp", + "version": "3.0.22-cpp", "style": "dist/style.css", "main": "dist/nutui.react.umd.js", "module": "dist/es/packages/nutui.react.build.js", diff --git a/src/packages/barrage/__tests__/barrage.spec.tsx b/src/packages/barrage/__tests__/barrage.spec.tsx index 809d5d647e..41d2b79ab9 100644 --- a/src/packages/barrage/__tests__/barrage.spec.tsx +++ b/src/packages/barrage/__tests__/barrage.spec.tsx @@ -88,3 +88,25 @@ test('should danmu rows top', async () => { { timeout: 4000 } ) }) + +describe('barrage.taro document guard logic', () => { + test('skips createElement when document.createElement is not a function', () => { + const original = document.createElement.bind(document) + // @ts-expect-error simulate non-H5 Taro env + document.createElement = undefined + + const shouldSkip = + typeof document === 'undefined' || + typeof document.createElement !== 'function' + expect(shouldSkip).toBe(true) + + document.createElement = original + }) + + test('does not skip createElement in normal H5 env', () => { + const shouldSkip = + typeof document === 'undefined' || + typeof document.createElement !== 'function' + expect(shouldSkip).toBe(false) + }) +}) diff --git a/src/packages/imagepreview/__test__/imagepreview.spec.tsx b/src/packages/imagepreview/__test__/imagepreview.spec.tsx index 152d218ac8..f6ecb8cb3f 100644 --- a/src/packages/imagepreview/__test__/imagepreview.spec.tsx +++ b/src/packages/imagepreview/__test__/imagepreview.spec.tsx @@ -196,3 +196,25 @@ describe('ImagePreview Component', () => { }) }) }) + +describe('imagepreview.taro document guard logic', () => { + test('skips addEventListener when document.addEventListener is not a function', () => { + const original = document.addEventListener + // @ts-expect-error simulate non-H5 Taro env + document.addEventListener = undefined + + const shouldSkip = + typeof document === 'undefined' || + typeof document.addEventListener !== 'function' + expect(shouldSkip).toBe(true) + + document.addEventListener = original + }) + + test('does not skip addEventListener in normal H5 env', () => { + const shouldSkip = + typeof document === 'undefined' || + typeof document.addEventListener !== 'function' + expect(shouldSkip).toBe(false) + }) +}) diff --git a/src/packages/swipe/__tests__/swipe.spec.tsx b/src/packages/swipe/__tests__/swipe.spec.tsx index 83901c44d3..d45a9e8438 100644 --- a/src/packages/swipe/__tests__/swipe.spec.tsx +++ b/src/packages/swipe/__tests__/swipe.spec.tsx @@ -96,3 +96,28 @@ test('base swipe content', async () => { container.querySelector('.nut-swipe .nut-swipe-right .nut-button-wrap') ).toHaveTextContent('购物车') }) + +describe('swipe.taro document guard logic', () => { + test('skips addEventListener when document.addEventListener is not a function', () => { + const addSpy = vi.spyOn(document, 'addEventListener') + const original = document.addEventListener + + // @ts-expect-error simulate non-H5 Taro env + document.addEventListener = undefined + + const shouldSkip = + typeof document === 'undefined' || + typeof document.addEventListener !== 'function' + expect(shouldSkip).toBe(true) + + document.addEventListener = original + addSpy.mockRestore() + }) + + test('does not skip addEventListener in normal H5 env', () => { + const shouldSkip = + typeof document === 'undefined' || + typeof document.addEventListener !== 'function' + expect(shouldSkip).toBe(false) + }) +}) From a6d7fdedb47aedc7426e98a1d8c4d574614f949f Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Fri, 28 Aug 2026 22:54:48 +0800 Subject: [PATCH 4/7] fix(progress): map ariaLabel prop to aria-label attribute; update snapshots Co-Authored-By: Claude --- .../__test__/__snapshots__/address.spec.tsx.snap | 14 +++++++------- .../__tests__/__snapshots__/cascader.spec.tsx.snap | 2 ++ .../cell/__test__/__snapshots__/cell.spec.tsx.snap | 4 ++++ .../__test__/__snapshots__/checkbox.spec.tsx.snap | 5 ++++- .../grid/__test__/__snapshots__/grid.spec.tsx.snap | 1 + .../__test__/__snapshots__/image.spec.tsx.snap | 1 + .../_test_/__snapshots__/index.spec.tsx.snap | 4 ++++ .../__tests__/__snapshots__/overlay.spec.tsx.snap | 1 + src/packages/overlay/__tests__/overlay.spec.tsx | 1 + src/packages/progress/progress.tsx | 2 ++ 10 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/packages/address/__test__/__snapshots__/address.spec.tsx.snap b/src/packages/address/__test__/__snapshots__/address.spec.tsx.snap index 86979e3e48..fa51247148 100644 --- a/src/packages/address/__test__/__snapshots__/address.spec.tsx.snap +++ b/src/packages/address/__test__/__snapshots__/address.spec.tsx.snap @@ -1,15 +1,15 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`Address: exist defaultIcon & selectIcon 1`] = `"
请选择地址
  • 123
    探探鱼
    182****1718
    北京市次渠镇通州区
  • 123
    探探鱼
    182****1718
    钓鱼岛钓鱼岛全区
  • 456
    探探鱼
    182****1718
    北京市大兴区科创十一街18号院京东大厦
"`; +exports[`Address: exist defaultIcon & selectIcon 1`] = `"
"`; -exports[`Address: show cascader false 1`] = `"
选择地址
请选择
浙江
湖南
福建
北京
"`; +exports[`Address: show cascader false 1`] = `"
"`; -exports[`Address: show custom icon 1`] = `"
选择地址
请选择
浙江
湖南
福建
北京
"`; +exports[`Address: show custom icon 1`] = `"
"`; -exports[`Address: show custom icon 2`] = `"
请选择地址
  • 探探鱼
    182****1718
    北京市次渠镇通州区
  • ,
    探探鱼
    182****1718
    钓鱼岛钓鱼岛全区
  • ,
    探探鱼
    182****1718
    北京市大兴区科创十一街18号院京东大厦
"`; +exports[`Address: show custom icon 2`] = `"
"`; -exports[`Address: show custom true 1`] = `"
选择地址
请选择
浙江
湖南
福建
北京
"`; +exports[`Address: show custom true 1`] = `"
"`; -exports[`Address: show elevator 1`] = `"
选择地址
热门城市
选择省份/地区
A
安徽
B
北京
C
重庆
F
福建
G
贵州
广东
广西
甘肃
H
河北
河南
湖南
湖北
S
山东
山西
上海
陕西
四川
Z
浙江
A
B
C
F
G
H
S
Z
"`; +exports[`Address: show elevator 1`] = `"
"`; -exports[`Address: show exist 1`] = `"
选择地址
  • 探探鱼
    182****1718
    北京市次渠镇通州区
  • ,
    探探鱼
    182****1718
    钓鱼岛钓鱼岛全区
  • ,
    探探鱼
    182****1718
    北京市大兴区科创十一街18号院京东大厦
"`; +exports[`Address: show exist 1`] = `"
"`; diff --git a/src/packages/cascader/__tests__/__snapshots__/cascader.spec.tsx.snap b/src/packages/cascader/__tests__/__snapshots__/cascader.spec.tsx.snap index 5f66a078d4..2f3e8d0f68 100644 --- a/src/packages/cascader/__tests__/__snapshots__/cascader.spec.tsx.snap +++ b/src/packages/cascader/__tests__/__snapshots__/cascader.spec.tsx.snap @@ -11,11 +11,13 @@ exports[`Cascader > value 1`] = `
`; exports[`Cascader > visible true 1`] = `