我们的聊天机器人的某些答案很长。网络聊天会自动滚动到底部,因此用户必须向上滚动才能到达气泡顶部并开始阅读。
我已经实现了一个自定义渲染器(反应),将答案包装到一个自定义组件中,该组件只是将答案包装到div标签中。我还实现了一段简单的代码以滚动到气泡顶部。
const MyCustomActivityContainer = ({ children }) => {
const triggerScrollTo = () => {
if (scrollRef && scrollRef.current) {
(scrollRef.current as any).scrollIntoView({
behavior: 'smooth',
block: 'start',
})
}
}
const scrollRef: React.RefObject<HTMLDivElement> = React.createRef()
return (
<div ref={ scrollRef } onClick={ triggerScrollTo }>
{ children }
</div>
)
}
export const activityMiddleware = () => next => card => {
if (/* some conditions */) {
return (
<MyCustomActivityContainer>
{ next(card) }
</MyCustomActivityContainer>
);
} else {
return (
{ next(card) }
)
}
};
但这仅在滚动条滑块不在其最低位置(向下滚动至少{1个像素,see here)时才有效。问题是useScrollToBottom挂钩,如果滚动条完全向下滚动,它总是自动滚动到底部。
是否有任何方法可以覆盖滚动行为或暂时禁用scrollToBottom功能?
答案 0 :(得分:2)
由于没有可复制的示例,我只能猜测。
而且我也必须对这个问题做出一些猜测。
因为尚不清楚什么不起作用:
<div>
中的MyCustomActivityContainer
并随后调用triggerScrollTo
不会导致滚动?
那会很奇怪,但是谁知道呢。在这种情况下,我怀疑没有可复制的示例,有人会帮助您。或者您是说您可以将消息滚动到视图中,但是如果它已经在视图中,那么当用户仍在阅读消息时,新消息可能会导致滚动。
就是这样,但是与您声明您的消息很长的声明相矛盾,因为这将是短消息的问题,而不是长消息的问题。
但是无论如何,您应该能够解决该问题。
如果在最低位置偏离1个像素的情况下仍能正常工作,则只需滚动该1个像素即可。您需要找到可滚动元素。并执行scrollable_element.scrollTop -= 1
。我测试了这种方法here。并且有效(其中可滚动元素是<p>
的祖父母)
还是您尝试在消息到达时自动滚动? ?那是真正的问题,但是您忘了提及它,并且没有发布尝试自动滚动的代码吗?
在这种情况下,您可以尝试使用setTimeout()
并推迟滚动,例如200ms
。
此数字基于我从来源收集的信息:
100ms
和34ms
react-scroll-to-bottom 中有一些启发式方法可能会解决问题 https://github.com/compulim/react-scroll-to-bottom/blob/3eb21bc469ee5f5095a431ac584be29a0d2da950/packages/component/src/ScrollToBottom/Composer.js
当前,没有可靠的方法来检查“滚动”事件是否由于用户手势,程序化滚动或Chrome合成的“滚动”事件而触发,以补偿尺寸变化。因此,我们将尽最大努力来猜测它是否由用户手势触发,并在其朝向开始方向时禁用粘滞。
对于我们观察到的情况,#1在#2之前发射了约20ms。该stickyCheckTimeout有可能在1到2之间进行调度。这意味着,如果仅查看#1来决定是否应该滚动,则我们将始终滚动,以反对用户的意图。
这就是为什么我认为您应该使用setTimeout()
答案 1 :(得分:2)
由于没有可复制的代码可供我调整并向您展示。我的建议是稍微调整代码。当新消息到达时,Chatbot需要不断地流数据,以计算为消息创建的div元素的高度。如果div元素大于窗口小部件的高度,请滚动到顶部,否则您可以选择保持不变。