fix(viewer): 安卓 Chromium 上看图控件触摸判定错乱 —— 拦掉重复的 touch* 事件流
现象:iOS 手机端手势完全正常,安卓(Edge/Chrome)看大图时切图极难触发、放大与拖动也常出问题。
真因(真 Chromium 实测的事件计数与 id):一次单指滑动同时收到 pointerdown ×1 与 touchstart ×1,
两者用的是**不同的 id 体系**(pointerdown: pointerId=5 / touchstart: touch.identifier=0)。
Viewer 的 pointerdown 里:
if (options.zoomOnTouch && options.zoomable && Object.keys(pointers).length > 1) action = ACTION_ZOOM;
于是同一根手指被记成两个键 ⇒ 被判定成「两根手指捏合」⇒ 动作误派成 ZOOM,切图/平移都不对。
iOS 上两套 id 恰好同值(WebKit 的 pointerId 就是 touch identifier)⇒ 只有一个键 ⇒ 一切正常,
这正解释了为什么只有安卓坏。
修法:在看图容器那层用**捕获阶段**把 touch* 停掉,只留 pointer 一套(捏合缩放照旧走 pointer 路径)。
只影响 .viewer-container 内部,页面其它地方的触摸不受影响。
验收(本机模拟):一刀切图仍正常 ✓;两指捏合仍可用(图片宽 351 → 1193)✓;jsdom 9 套件全绿 ✓。
注:本机模拟复现不出该 bug(模拟器不是真安卓),但上面的事件计数与 id 差异是实测的,
实际效果请老师在安卓真机上确认。
This commit is contained in:
1 parent
af7c730edc
commit
05604dcff2
3 files changed
+17
-3
No files matched your search
+2
-2
@@ -165,7 +165,7 @@ RUN php -r "file_exists('.env') || copy('.env.example', '.env');" \
|
||||
RUN printf '%s\n' \
|
||||
'c0e513ec8e93fd81b34b3c6de5cf5eb8 ./public/js/context-js/context-js.js' \
|
||||
'c0e513ec8e93fd81b34b3c6de5cf5eb8 ./resources/js/context-js.js' \
|
||||
'27e13507a629aa3ae9f21496a6cf0ebf ./resources/views/user/images.blade.php' \
|
||||
'cfaad16720f1646fda4426b832e12122 ./resources/views/user/images.blade.php' \
|
||||
| md5sum -c - \
|
||||
&& grep -q "assetVersion('js/context-js/context-js.js')" ./resources/views/user/images.blade.php \
|
||||
&& grep -q 'isIOSWebKit' ./public/js/context-js/context-js.js \
|
||||
@@ -208,7 +208,7 @@ RUN APP_SRC_MD5=$(find app config routes -type f -print0 2>/dev/null | sort -z |
|
||||
"fork_sha=${FORK_SHA}" \
|
||||
"lsky_commit=${LSKY_COMMIT}" \
|
||||
"context_js_md5=c0e513ec8e93fd81b34b3c6de5cf5eb8" \
|
||||
"images_blade_md5=27e13507a629aa3ae9f21496a6cf0ebf" \
|
||||
"images_blade_md5=cfaad16720f1646fda4426b832e12122" \
|
||||
"app_src_md5=${APP_SRC_MD5}" \
|
||||
"app_js_md5=${APP_JS_MD5}" \
|
||||
"app_css_md5=${APP_CSS_MD5}" \
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
# 三个文件各自的 md5(与 Dockerfile「自证 2」里的期望值一致):
|
||||
# c0e513ec8e93fd81b34b3c6de5cf5eb8 src/resources/js/context-js.js
|
||||
# c0e513ec8e93fd81b34b3c6de5cf5eb8 src/public/js/context-js/context-js.js
|
||||
# 27e13507a629aa3ae9f21496a6cf0ebf src/resources/views/user/images.blade.php
|
||||
# cfaad16720f1646fda4426b832e12122 src/resources/views/user/images.blade.php
|
||||
#
|
||||
# 上游原文件 md5(改动前,供比对):
|
||||
# c8e57f6232848ca8277341ddf1a3a7a6 resources/js/context-js.js
|
||||
|
||||
@@ -547,6 +547,20 @@ class="relative inline-flex h-4 w-7 shrink-0 items-center rounded-full bg-brand
|
||||
* (教训:第三方控件遇到根节点 zoom,就把它那层缩回去,别逐条路径打补丁。) */
|
||||
|
||||
|
||||
/* 安卓 Chromium 专属问题:它会**同时**派发 touch* 和 pointer* 两套事件,而 Viewer 把
|
||||
* 同一个手指记成两个键(touch.identifier vs pointerId)——实测 pointerId=5 / touchId=0
|
||||
* 不同值。于是它内部 `Object.keys(pointers).length > 1` 成立,把动作误判成 ACTION_ZOOM
|
||||
* (以为是两根手指捏合)⇒ 手机上切图/放大/拖动全都不稳。iOS 上两套 id 恰好同值,所以没事。
|
||||
* 修法:在看图容器这层用**捕获阶段**把 touch* 拦下,不让它到 Viewer —— 只留 pointer 一套,
|
||||
* 捏合缩放照旧走 pointer 路径。只影响看图控件内部,页面其它地方的触摸不受影响。 */
|
||||
['touchstart', 'touchmove', 'touchend', 'touchcancel'].forEach(type => {
|
||||
document.addEventListener(type, (e) => {
|
||||
if (e.target instanceof Element && e.target.closest('.viewer-container')) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
}, true);
|
||||
});
|
||||
|
||||
$photos.justifiedGallery(gridConfigs);
|
||||
|
||||
let albumsInfinite = null;
|
||||
|
||||
Reference in new issue
Block a user