滚动到botframework网络聊天中气泡的顶部

时间:2020-04-03 12:26:14

标签: javascript reactjs botframework web-chat

我们的聊天机器人的某些答案很长。网络聊天会自动滚动到底部,因此用户必须向上滚动才能到达气泡顶部并开始阅读。

我已经实现了一个自定义渲染器(反应),将答案包装到一个自定义组件中,该组件只是将答案包装到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功能?

2 个答案:

答案 0 :(得分:2)

由于没有可复制的示例,我只能猜测。
而且我也必须对这个问题做出一些猜测。
因为尚不清楚什么不起作用:

  1. 您是否意味着单击<div>中的MyCustomActivityContainer并随后调用triggerScrollTo不会导致滚动? 那会很奇怪,但是谁知道呢。在这种情况下,我怀疑没有可复制的示例,有人会帮助您。
  2. 或者您是说您可以将消息滚动到视图中,但是如果它已经在视图中,那么当用户仍在阅读消息时,新消息可能会导致滚动。
    就是这样,但是与您声明您的消息很长的声明相矛盾,因为这将是短消息的问题,而不是长消息的问题。

    但是无论如何,您应该能够解决该问题。
    如果在最低位置偏离1个像素的情况下仍能正常工作,则只需滚动该1个像素即可。您需要找到可滚动元素。并执行scrollable_element.scrollTop -= 1。我测试了这种方法here。并且有效(其中可滚动元素是<p>的祖父母)

  3. 还是您尝试在消息到达时自动滚动? ?那是真正的问题,但是您忘了提及它,并且没有发布尝试自动滚动的代码吗?

    在这种情况下,您可以尝试使用setTimeout()并推迟滚动,例如200ms。 此数字基于我从来源收集的信息:

    1. BotFramework-WebChat 使用 react-scroll-to-bottom
    2. react-scroll-to-bottom 中,有些超时100ms34ms
    3. BotFramework-WebChat 不会重新定义它们
    4. react-scroll-to-bottom 中有一些启发式方法可能会解决问题 https://github.com/compulim/react-scroll-to-bottom/blob/3eb21bc469ee5f5095a431ac584be29a0d2da950/packages/component/src/ScrollToBottom/Composer.js

      当前,没有可靠的方法来检查“滚动”事件是否由于用户手势,程序化滚动或Chrome合成的“滚动”事件而触发,以补偿尺寸变化。因此,我们将尽最大努力来猜测它是否由用户手势触发,并在其朝向开始方向时禁用粘滞。


      https://github.com/compulim/react-scroll-to-bottom/blob/f19b14d6db63dcb07ffa45b4433e72284a9d53b6/packages/component/src/ScrollToBottom/Composer.js#L91

      对于我们观察到的情况,#1在#2之前发射了约20ms。该stickyCheckTimeout有可能在1到2之间进行调度。这意味着,如果仅查看#1来决定是否应该滚动,则我们将始终滚动,以反对用户的意图。

      这就是为什么我认为您应该使用setTimeout()

答案 1 :(得分:2)

由于没有可复制的代码可供我调整并向您展示。我的建议是稍微调整代码。当新消息到达时,Chatbot需要不断地流数据,以计算为消息创建的div元素的高度。如果div元素大于窗口小部件的高度,请滚动到顶部,否则您可以选择保持不变。