如何实现动态对话框输出的效果 | 豆包MarsCode AI 刷题

158 阅读2分钟

引言:在青训营前端训练营的小项目中,有一个组件能力要求,就是需要支持LLM流式返回结果,实现逐行打印效果,本篇文章主要讲述如何使用一种简单的方式来实现这一功能。

预先分析

首先,我们需要分析一下具体需求。LLM流式返回结果,逐行打印,代表虽然我们前端接受到的信息可能是完整的一段文字,但是在输出或者说呈现给用户的时候,是按照一行一行、一个字一个字输出的。

那么如何完成这一组件功能呢?

当然一种方式是我们可以从网上查找已经有这个功能的封装好的组件,直接调用;另一种方式则是从底层逻辑入手,使用前端开发老三件进行手工开发。

具体步骤

具体来讲,HTML,CSS,JavaScript各自承担起自己的分内工作,即:

  • HTML:创建一个对话框组件,通过<div>元素来容纳消息。
  • CSS:为对话框设计简单的样式,例如背景色、边框、阴影等,使其更加美观。
  • JavaScript:掌控输出的逻辑时机。(实际上的主要工作就是拆分字符并确定输出的时间间隔)

代码编写

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>对话框组件</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            padding: 20px;
        }
        .dialogue-box {
            background: white;
            border: 1px solid #ccc;
            border-radius: 5px;
            padding: 20px;
            max-width: 400px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            overflow: hidden;
        }
        .message {
            margin: 10px 0;
            line-height: 1.5;
        }
    </style>
</head>
<body>

<div class="dialogue-box" id="dialogueBox">
    <div id="messages"></div>
</div>

<script>
    const messagesContainer = document.getElementById('messages');

    // 模拟流式返回的消息
    const messages = [
        "你好!我可以帮你什么?",
        "这里是一个示例对话框组件。",
        "我们将实现逐行打印效果。",
        "请耐心等待,消息将逐条显示。"
    ];

    function printMessage(message, index) {
        const messageElement = document.createElement('div');
        messageElement.className = 'message';
        messagesContainer.appendChild(messageElement);

        // 模拟逐行打印效果
        let charIndex = 0;
        const interval = setInterval(() => {
            if (charIndex < message.length) {
                messageElement.textContent += message.charAt(charIndex);
                charIndex++;
            } else {
                clearInterval(interval);
            }
        }, 100); // 每100毫秒打印一个字符
    }

    function startPrintingMessages() {
        messages.forEach((message, index) => {
            setTimeout(() => {
                printMessage(message, index);
            }, index * 3000); // 每条消息间隔3秒
        });
    }

    // 开始打印消息
    startPrintingMessages();
</script>

</body>
</html>

HTML 和CSS部分比较常规好理解,就不再赘述了。

JavaScript的部分要复杂一些: 首先,使用const messages定义要打印的消息数组。

然后定义printMessage函数逐字符打印消息,使用setInterval模拟字符逐个显示的效果,设置字符逐个显示的时间间隔。

最后定义startPrintingMessage函数负责定时调用printMessage,使得每条消息的输出间隔一段时间。

尾言

这样我们就完成了一个简单的能够实现逐行输出的对话框了。