From 4c478b16e3f1ed3d6f3ca339259d4610ee395ef5 Mon Sep 17 00:00:00 2001 From: xsl Date: Tue, 13 Oct 2026 00:32:44 +0800 Subject: [PATCH] fix(h5): prioritize horizontal report image gestures --- docs/报告页滑动防冲突-2026-10-13.md | 4 ++-- graphify-out/manifest.json | 16 ++++++++-------- h5/js/app.js | 2 +- h5/js/swipe-track.js | 4 ++-- h5/test/report-touch-layout.mjs | 3 ++- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/docs/报告页滑动防冲突-2026-10-13.md b/docs/报告页滑动防冲突-2026-10-13.md index 028ad9d..d8a8df7 100644 --- a/docs/报告页滑动防冲突-2026-10-13.md +++ b/docs/报告页滑动防冲突-2026-10-13.md @@ -3,11 +3,11 @@ 仅优化报告详情卡的手势,不修改报告数据、算法或基础信息页的滑动参数。 - 图片区域可横向跟手切换;说明文字不触发横滑,页签仍可点击或键盘切换。 -- 方向判定由 8px、横向略大于纵向,改为移动超过 12px 且横向位移大于纵向的 1.5 倍才进入横滑。其余明确移动交给纵向阅读,一次手势锁定后不重新判方向。 +- 当前试用横向优先:移动超过 12px 且横向位移大于纵向的 2/3 即进入横滑;只有纵向位移达到横向的 1.5 倍时才锁定竖滑。一次手势锁定后不重新判方向。之前上线的竖向优先版本要求横向大于纵向的 1.5 倍才横滑。 - 横滑过程中冻结卡片当前高度,包括图片/字体延迟加载导致的尺寸更新;松手或取消后再恢复当前页签高度,并沿用平滑高度过渡。 - 首尾保留阻尼反馈,但回弹位移最大为 16 CSS px,不允许拉出大片空白。 - 保留浏览器原生纵向滚动、图片点击放大、取消复位与无障碍页签行为。不尝试拦截微信系统返回手势。 验证:`node h5/test/report-touch-layout.mjs` 检查真实移动触摸横滑、斜滑、文字区不切页、图片与文字区竖向滚动、拖动期间高度不变、边缘位移上限和原有布局/交互;`node h5/test/profile-interaction.mjs` 回归共用滑动组件的基础信息页。 -本地上述两项测试均通过。发布沿用 Git bundle 快进同步至 `/home/ubuntu/juzi`,重启 `juzi-h5.service`,再经公网运行同一报告交互测试并检查服务健康及静态资源一致性。不代用户推送 origin,不包含未追踪的 `new_feedback/`。最终手机微信体验仍需真机复验。 +之前的竖向优先版本已发布;当前横向优先版本已通过本地报告交互测试,按用户要求发版。发布沿用 Git bundle 快进同步至 `/home/ubuntu/juzi`,重启 `juzi-h5.service`,再经公网运行同一报告交互测试并检查服务健康及静态资源一致性。不代用户推送 origin,不包含未追踪的 `new_feedback/`。最终手机微信体验仍需真机复验。 diff --git a/graphify-out/manifest.json b/graphify-out/manifest.json index 7e89ed0..d7b3b0a 100644 --- a/graphify-out/manifest.json +++ b/graphify-out/manifest.json @@ -40,8 +40,8 @@ "semantic_hash": "" }, "h5/js/app.js": { - "mtime": 1791822027.245803, - "ast_hash": "4034c98d93fbaa0534de20e7ac47cf41", + "mtime": 1791822609.9707172, + "ast_hash": "7841b52a3f703c468951211b93003dfe", "semantic_hash": "" }, "h5/js/head-pose.js": { @@ -1920,13 +1920,13 @@ "semantic_hash": "" }, "h5/js/swipe-track.js": { - "mtime": 1791822192.248705, - "ast_hash": "da9340563e73df85502b1e8860b769e5", + "mtime": 1791822609.9707172, + "ast_hash": "79f7941362f09f5a43ca7c2ca73bef06", "semantic_hash": "" }, "h5/test/report-touch-layout.mjs": { - "mtime": 1791822203.777799, - "ast_hash": "8c83b7333fc0f8e3964fbaf156e32f2b", + "mtime": 1791822609.9707172, + "ast_hash": "90a721a135acb4f63b30bf9b4c9653be", "semantic_hash": "" }, "h5/test/scan-placeholder.mjs": { @@ -1965,8 +1965,8 @@ "semantic_hash": "" }, "docs/\u62a5\u544a\u9875\u6ed1\u52a8\u9632\u51b2\u7a81-2026-10-13.md": { - "mtime": 1791822192.248705, - "ast_hash": "cd09aff1f65d7a9dee76b2d7c6455cbe", + "mtime": 1791822609.9707172, + "ast_hash": "17fc9e4b6fedfda7fb62763a8c878656", "semantic_hash": "" }, "docs/\u62a5\u544a\u9876\u90e8\u8bc4\u5206\u4e0e\u5e74\u9f84\u6392\u7248-2026-10-13.md": { diff --git a/h5/js/app.js b/h5/js/app.js index ae55720..70d0521 100644 --- a/h5/js/app.js +++ b/h5/js/app.js @@ -1521,7 +1521,7 @@ viewport.style.height = (panels[lower].offsetHeight * (1 - ratio) + panels[upper].offsetHeight * ratio) + 'px'; } var swipe = SwipeTrack.create(viewport, track, { count: panels.length, gestureTarget: card, - gestureSelector: '.viz-frame', startThreshold: 12, directionRatio: 1.5, maxOverscroll: 16, + gestureSelector: '.viz-frame', startThreshold: 12, directionRatio: 2 / 3, maxOverscroll: 16, onStart: function () { viewport.style.height = viewport.getBoundingClientRect().height + 'px'; }, onCancel: height, onSelect: function (i) { setDetailTab(card, String(i)); } }); detailSwipes.set(card, { swipe: swipe, height: height }); diff --git a/h5/js/swipe-track.js b/h5/js/swipe-track.js index 00adc23..a045268 100644 --- a/h5/js/swipe-track.js +++ b/h5/js/swipe-track.js @@ -34,8 +34,8 @@ window.SwipeTrack = (function () { if (!drag.horizontal) { var threshold = options.startThreshold || 8, ratio = options.directionRatio || 1; if (Math.max(Math.abs(dx), Math.abs(dy)) <= threshold) return; - // Ambiguous diagonal movement belongs to page scrolling. Once locked, - // neither direction can steal this gesture before the finger lifts. + // Each caller chooses its diagonal bias. Once locked, neither direction + // can steal this gesture before the finger lifts. if (Math.abs(dy) * ratio >= Math.abs(dx)) { drag.vertical = true; return; } drag.horizontal = true; if (options.onStart) options.onStart(index); diff --git a/h5/test/report-touch-layout.mjs b/h5/test/report-touch-layout.mjs index 53643d5..692a595 100644 --- a/h5/test/report-touch-layout.mjs +++ b/h5/test/report-touch-layout.mjs @@ -120,7 +120,8 @@ try { await drag(card, 25, { pause: 160 }); assert.equal(await selected(card), '1', 'short slow drag snaps back'); await drag(card, 100, { cancel: true }); assert.equal(await selected(card), '1', 'cancellation restores selection'); await drag(card, 2, { dy: -90 }); assert.equal(await selected(card), '1', 'vertical scrolling preserves tab'); - await drag(card, 65, { dy: -60 }); assert.equal(await selected(card), '1', 'ambiguous diagonal scrolling does not switch tabs'); + await drag(card, 65, { dy: -60 }); assert.equal(await selected(card), '0', 'diagonal image gesture prioritizes horizontal switching'); + await card.locator('.dtab').nth(1).click(); await page.waitForTimeout(400); await drag(card, 100, { text: true }); assert.equal(await selected(card), '1', 'horizontal dragging on analysis text does not switch tabs'); await drag(card, 2, { dy: -90, text: true }); assert.equal(await selected(card), '1', 'reading text keeps vertical scrolling and current tab'); await drag(card, 40, { flick: true }); assert.equal(await selected(card), '0', 'short fast flick goes back');