Skip to content

fix: prevent spurious scroll-triggered approval drawer re-opens; remove unreliable scroll-compensation#530

Draft
Copilot wants to merge 5 commits into6.10from
copilot/fix-approval-drawer-issues
Draft

fix: prevent spurious scroll-triggered approval drawer re-opens; remove unreliable scroll-compensation#530
Copilot wants to merge 5 commits into6.10from
copilot/fix-approval-drawer-issues

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 27, 2026

Two bugs in the scroll-to-bottom auto-open approval drawer logic, plus removal of a timing-dependent UX compensation that couldn't reliably solve drawer content overlap.

Changes

flow.js — fix scroll trigger logic

  • isAtBottom(): was scrollHeight <= clientHeight || ... — short pages (content fits in viewport) incorrectly returned true always. Fixed to require content actually overflows (scrollHeight > clientHeight) before treating scroll position as "at bottom"
  • Duplicate trigger prevention: replaced lastAtBottom edge-detection with hasTriggered flag + MutationObserver that resets the flag when drawer closes — prevents repeated triggers while scrolling at bottom
  • isDrawerOpen(): tightened selector from .amis-dialog-widget.approval-drawer + offsetParent check to .steedos-amis-instance-approval-drawer-container .approval-drawer existence check

approve.js — remove scrollToBottom compensation

The triggerSource = 'scrollToBottom'scrollToBottom() path (jQuery animate scroll after drawer opens) was unreliable due to timing sensitivity. Both the scrollToBottom function and the triggerSource dataset tracking are removed. The layout-level drawer overlap issue is deferred to a separate PR.

Original prompt

问题描述

审批单中滚动到底部会自动弹出底部审批栏(approval drawer),存在以下问题:

核心 UX 问题

用户慢慢滚动到底部是为了查看表单内容,滚动过程中审批栏突然从底部弹出(带动画),严重打断用户阅读思路。

误触发 Bug

用户反馈:有时向上滚动或其它非预期情况下,审批栏也会无故从底部弹出。

重现步骤

  1. 打开一个待审批的审批单(inbox)
  2. 表单内容较长,需要滚动查看
  3. 慢慢向下滚动滚动条到底部
  4. 预期:用户看完底部内容后主动点击审批按钮
  5. 实际:滚动到底部时审批栏自动弹出,且带有滑入动画,打断阅读

技术分析

分支6.10

涉及文件

  • packages/@steedos-widgets/amis-lib/src/workflow/flow.jsgetScrollToBottomAutoOpenApproveDrawerScript 函数(第1259-1305行)
  • packages/@steedos-widgets/amis-lib/src/workflow/approve.jsgetApprovalDrawerSchema 函数(第699-964行)

根因1:scroll 事件无方向判断(误触发元凶)

wheel 事件判断了 e.deltaY > 0(向下滚),但 scroll 事件只判断了"从非底部→底部",完全没有判断滚动方向

导致以下场景误触发:

  • 用户向上滚动后松手,浏览器惯性回弹到底部
  • 页面内容异步加载导致 scrollHeight 变化
  • 窗口 resize 导致 clientHeight 变化
  • 审批历史等内容折叠/展开导致 scrollHeight 突变

当前有问题的 scroll 监听代码(flow.js 第1293-1301行):

bodyEl.addEventListener('scroll', function () {
  var atBottom = isAtBottom();
  if (!lastAtBottom && atBottom && !isDrawerOpen()) {
    btn.dataset.triggerSource = 'scrollToBottom';
    btn.click();
  }
  lastAtBottom = atBottom;
});

根因2:isDrawerOpen 选择器不匹配

当前代码:

function isDrawerOpen() {
  var dr = document.querySelector('.amis-dialog-widget.approval-drawer');
  return dr && dr.offsetParent !== null;
}

但 approve.js 中 drawer 的 className 是 "approval-drawer absolute",挂载在 .steedos-amis-instance-approval-drawer-container 下。选择器不匹配可能导致 isDrawerOpen() 始终返回 false,从而重复触发弹出。

应改为:

function isDrawerOpen() {
  var dr = document.querySelector('.steedos-amis-instance-approval-drawer-container .approval-drawer');
  return !!dr;
}

根因3:弹出后自动 scrollToBottom 加重干扰

approve.js 中 drawer 打开后如果是滚动触发的(第870-882行),会执行 $(instanceViewBody).animate({scrollTop: ...}),导致画面被动画拉到最底部,双重打断用户。

var scrollToBottom = function(){
  setTimeout(function(){
    const instanceViewBody = document.querySelector(CONFIG.bodySelector);
    if (instanceViewBody){
      $(instanceViewBody).animate({scrollTop: $(instanceViewBody).prop("scrollHeight")});
    }
  }, 500);
}
var btn = document.querySelector(CONFIG.approveButtonSelector);
if (btn && btn.dataset.triggerSource === 'scrollToBottom') {
  scrollToBottom();
  delete btn.dataset.triggerSource;
}

根因4:短表单页面误触发

isAtBottom()scrollHeight <= clientHeight 时直接返回 true,导致内容不足一屏时页面加载后立即触发弹出。

修复建议

1. scroll 事件加方向判断

通过前后 scrollTop 差值判断滚动方向,只有向下滚动且到底才触发。不能去掉 scroll 只保留 wheel,因为:

  • 手机端触屏滑动不触发 wheel 事件
  • PC 上拖拽滚动条不触发 wheel 事件
  • 键盘方向键/PgDn 不触发 wheel 事件

建议实现:

var lastScrollTop = bodyEl.scrollTop;
bodyEl.addEventListener('scroll', function () {
  var currentScrollTop = bodyEl.scrollTop;
  var isScrollingDown = currentScrollTop > lastScrollTop;
  var atBottom = isAtBottom();
  if (isScrollingDown && atBottom && !hasTriggered && !isDrawerOpen()) {
    hasTriggered = true;
    btn.dataset.triggerSource = 'scrollToBottom';
    btn.click();
  }
  lastScrollTop = currentScrollTop;
});

2. 修正 isDrawerOpen 选择器

改为匹配实际 DOM 结构:.steedos-amis-instance-approval-drawer-container .approval-drawer

3. 增加 hasTriggered 防重复触发标记

只触发一次,drawer 关闭后通过 MutationObserver 重置

4. 删除自动 scrollToBottom

approve.js 中去掉 drawer 打开后的 animate scrollTop 逻辑(第870-882行),改为只删除 triggerSource 标记:

var btn = document.querySelector(CONFIG.approveButtonSelector);
if (btn && btn.dataset.triggerSource === 'scrollToBottom') {
  delete btn.dataset.triggerSource;
}

5. isAtBottom 增加前置条件

改为 scrollHeight > clientHeight 时才检测是否到底,避免短表单页面误触发

6. 可选优化

缩短或去掉 drawer 滑入动画,使体验更接近老版本的 CSS 显隐方式

背景

老版本使用原生 JS+CSS 实现,审批栏通过显隐方式切换(瞬间出现,无动画,不改变页面布局),用户无体验投诉。新版本改用 amis Drawer 组件后引入了上述问题。

This pull request was created from Copilot chat.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

- Fix isDrawerOpen selector to match actual DOM structure
- Add hasTriggered flag with MutationObserver reset to prevent repeated triggers
- Add scroll direction check: only trigger when scrolling down
- Fix isAtBottom to require scrollHeight > clientHeight (avoids short-page false triggers)
- Remove auto scrollToBottom animation in approve.js drawer open handler

Co-authored-by: yinlianghui <6219465+yinlianghui@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix approval drawer auto-popup during scrolling fix: prevent spurious scroll-triggered approval drawer popup Feb 27, 2026
Copilot AI changed the title fix: prevent spurious scroll-triggered approval drawer popup fix: 修复审批单滚动到底部误触发审批栏弹出问题 Feb 27, 2026
… prevent content blockage

Co-authored-by: yinlianghui <6219465+yinlianghui@users.noreply.github.com>
Copilot AI changed the title fix: 修复审批单滚动到底部误触发审批栏弹出问题 fix: scroll body to new bottom after scroll-triggered approval drawer opens Feb 27, 2026
…of new approach

Co-authored-by: yinlianghui <6219465+yinlianghui@users.noreply.github.com>
Copilot AI changed the title fix: scroll body to new bottom after scroll-triggered approval drawer opens revert: remove smooth-scroll-to-bottom workaround for approval drawer UX Feb 27, 2026
…smooth-scroll patch

Co-authored-by: yinlianghui <6219465+yinlianghui@users.noreply.github.com>
Copilot AI changed the title revert: remove smooth-scroll-to-bottom workaround for approval drawer UX fix: clean up scroll-to-bottom approval drawer auto-open Feb 27, 2026
Copilot AI changed the title fix: clean up scroll-to-bottom approval drawer auto-open fix: prevent spurious scroll-triggered approval drawer re-opens; remove unreliable scroll-compensation Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants