添加新消息时滚动到底部

发布于 2025-02-07 16:57:11 字数 2915 浏览 1 评论 0 原文

我正在做聊天机器人。当用户给出新的输入或通过API发送数据时,我想滚动到聊天框的底部。

它不会滚动和滚动仅位于相同的位置,但是在聊天框中添加了数据

,我尝试了其他聊天机器人的代码,但也不起作用

var outputArea = $('#chat-output');
$('#user-input-form').on('submit', function (e) {
  e.preventDefault();

  var message = $('#user-input').val();

  outputArea.append(`
    <div class='bot-message'>
      <div class='message'>
        ${message}
      </div>
    </div>
  `);



  const req = https.request(options, (res) => {
    res.setEncoding('utf8');
    res.on('data', (d) => {
      const myobj = JSON.parse(d);
      if ('narrative' in myobj.conversationalResponse.responses[0]) {
        const temp = myobj.conversationalResponse.responses[0].narrative.text;
        outputArea.append(`
      <div class='user-message'>
        <div class='message'>
          ${temp}
        </div>
      </div>
    `);
      } else if ('imageUrl' in myobj.conversationalResponse.responses[0]) {
        const img = myobj.conversationalResponse.responses[0].imageUrl;
        if ('narrative' in myobj.conversationalResponse.responses[1]) {
          const text_r = myobj.conversationalResponse.responses[1].narrative.text;
          outputArea.append(`
      <div class='user-message'>
      <div class ="message">
      ${text_r}
      <a href=""></a>
      </div>
      </div>
    `);
        } else {
          outputArea.append(`
      <div class='user-message'>
        <div class='message'>
         <img src="" width="300" height="200">
        </div>
      </div>
    `);
        }
      }
    });
  });

  req.on('error', (error) => {
    console.error(error);
  });

  req.write(data);
  req.end();

  $('#user-input').val('');
.form-container {
  width: 400px;
  height: 450px;
  padding: 10px;
  background-color: white;
  overflow: scroll;
  position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chat-popup" id="myForm">
<div class="form-container">

  <div class="chat-output" id="chat-output">
    <div class="user-message">
      <div class="message">Hi! I'm Bot, what's up?</div>
    </div>
  </div>
  <div class="chat-input">
    <form action="#0" id="user-input-form" autocomplete="off">
      <input type="text" id="user-input" class="user-input" placeholder="Talk to the bot.">
    </form>
  </div>
  </br></br>
  <button type="button" class="btn cancel" onclick="closeForm()">Close</button>
</div>
</div>

I am making a chatbot. I want to scroll to the bottom of the chat box when a new input is given by the user or the Data is sent through API.

It doesn't scroll and scroll just stays in the same position but the data is being added in the chat box

I Have tried the code from other chat bot but it didn't work either

var outputArea = $('#chat-output');
$('#user-input-form').on('submit', function (e) {
  e.preventDefault();

  var message = $('#user-input').val();

  outputArea.append(`
    <div class='bot-message'>
      <div class='message'>
        ${message}
      </div>
    </div>
  `);



  const req = https.request(options, (res) => {
    res.setEncoding('utf8');
    res.on('data', (d) => {
      const myobj = JSON.parse(d);
      if ('narrative' in myobj.conversationalResponse.responses[0]) {
        const temp = myobj.conversationalResponse.responses[0].narrative.text;
        outputArea.append(`
      <div class='user-message'>
        <div class='message'>
          ${temp}
        </div>
      </div>
    `);
      } else if ('imageUrl' in myobj.conversationalResponse.responses[0]) {
        const img = myobj.conversationalResponse.responses[0].imageUrl;
        if ('narrative' in myobj.conversationalResponse.responses[1]) {
          const text_r = myobj.conversationalResponse.responses[1].narrative.text;
          outputArea.append(`
      <div class='user-message'>
      <div class ="message">
      ${text_r}
      <a href=""></a>
      </div>
      </div>
    `);
        } else {
          outputArea.append(`
      <div class='user-message'>
        <div class='message'>
         <img src="" width="300" height="200">
        </div>
      </div>
    `);
        }
      }
    });
  });

  req.on('error', (error) => {
    console.error(error);
  });

  req.write(data);
  req.end();

  $('#user-input').val('');
.form-container {
  width: 400px;
  height: 450px;
  padding: 10px;
  background-color: white;
  overflow: scroll;
  position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chat-popup" id="myForm">
<div class="form-container">

  <div class="chat-output" id="chat-output">
    <div class="user-message">
      <div class="message">Hi! I'm Bot, what's up?</div>
    </div>
  </div>
  <div class="chat-input">
    <form action="#0" id="user-input-form" autocomplete="off">
      <input type="text" id="user-input" class="user-input" placeholder="Talk to the bot.">
    </form>
  </div>
  </br></br>
  <button type="button" class="btn cancel" onclick="closeForm()">Close</button>
</div>
</div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

阳光①夏 2025-02-14 16:57:12

另一个有趣的方法是使用纯CSS,使用 flex-direction 方法,该方法通过为卷轴内部的内容内部创建包装器来起作用。

我已经在下面进行了快速演示(使用按钮和一些JavaScript添加新项目)。您也可以查看此独立的演示page

然后,技巧在于使用滚动器中使用列列逆转内容方向。由于项目在另一个容器中,因此它们不会“翻转”,而是始终将其排成下面。实际上,这使得滚动器每当添加东西时都会滚动到底部。

添加了奖励:保持滚动位置(主要是*)

,这是我对方法的真正喜欢的东西;每当用户开始滚动(向上)时,滚动器就不会在添加东西时失去其滚动位置。因此,如果已经将其滚动(默认情况下或用户)滚动到底部,则只会将其“粘贴”。这确保没有令人讨厌的内容跳跃,提供更好的用户体验。

*大多数情况下,由于只有iOS Safari不支持溢出锚,因此无论用户滚动位置如何,它始终会继续滚动容器。参见 https:// US/DOCS/WEB/CSS/OVERFLOW-CHART#browser_compatibility

演示

注:JavaScript仅是因为演示示例 - 解决方案本身纯粹是基于CSS的。

let scrollerContent = document.getElementById('scrollerContent');

document.getElementById('addItems').addEventListener('click', function() {
  let newChild = scrollerContent.lastElementChild.cloneNode(true);
  newChild.innerHTML = "Item " + (scrollerContent.children.length + 1);
  scrollerContent.appendChild(newChild);
});
.scroller {
    overflow: auto;
    height: 100px;
    display: flex;
    flex-direction: column-reverse;
    overflow-anchor: auto !important; /*  See https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor */
}

.scroller .scroller-content .item {
    height: 20px;
    transform: translateZ(0); /* fixes a bug in Safari iOS where the scroller doesn't update */
}
<div class="scroller">
  <div class="scroller-content" id="scrollerContent">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
    <div class="item">Item 4</div>
    <div class="item">Item 5</div>
    <div class="item">Item 6</div>
    <div class="item">Item 7</div>
    <div class="item">Item 8</div>
    <div class="item">Item 9</div>
    <div class="item">Item 10</div>
  </div>
</div>
<br/><br/>
<button id="addItems">Add more items</button>

Another interesting method is by using pure CSS, using the flex-direction method, which works by creating a wrapper for the content inside the scrolling element.

I've whipped up a quick demo below (with a button and some JavaScript for adding new items). You can also check out this separate demo-page.

The trick then lies in reversing the content direction using column-reverse in the scroller. Because the items are in another container, they don't get 'flipped' but instead always line up to the bottom. This, in fact, makes the scroller scrolled to the bottom whenever stuff is added.

Breakdown, click for demo

Added bonus: keeps scroll position (mostly*)

Also, and this is something I really like about the method; whenever the user has started scrolling (up), the scroller will not lose its scroll position when stuff is being added. So, it will only 'stick' tot the bottom if it was already scrolled (by default, or by the user) to the bottom. This makes sure there's no annoying content jumping, offering a better user experience.

* Mostly, because only iOS Safari doesn't support overflow-anchor, so it will always keep scrolling the container, regardless of user scroll position. See https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor#browser_compatibility

Demo

Note: the JavaScript is only because of demonstration-purposes: the solution itself is purely CSS-based.

let scrollerContent = document.getElementById('scrollerContent');

document.getElementById('addItems').addEventListener('click', function() {
  let newChild = scrollerContent.lastElementChild.cloneNode(true);
  newChild.innerHTML = "Item " + (scrollerContent.children.length + 1);
  scrollerContent.appendChild(newChild);
});
.scroller {
    overflow: auto;
    height: 100px;
    display: flex;
    flex-direction: column-reverse;
    overflow-anchor: auto !important; /*  See https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor */
}

.scroller .scroller-content .item {
    height: 20px;
    transform: translateZ(0); /* fixes a bug in Safari iOS where the scroller doesn't update */
}
<div class="scroller">
  <div class="scroller-content" id="scrollerContent">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
    <div class="item">Item 4</div>
    <div class="item">Item 5</div>
    <div class="item">Item 6</div>
    <div class="item">Item 7</div>
    <div class="item">Item 8</div>
    <div class="item">Item 9</div>
    <div class="item">Item 10</div>
  </div>
</div>
<br/><br/>
<button id="addItems">Add more items</button>

三五鸿雁 2025-02-14 16:57:12

我尝试了几种方法,并发现了 CSS-Tricks文章使用Overflow-Chandor。我建议您查看文章,因为它具有适当的解释。

#messages-container * {
  overflow-anchor: none;
}

#anchor {
  overflow-anchor: auto;
  height: 1px;
}
<div id="messages-container">
  <!-- Insert messages here -->
  <div id="anchor"></div>
</div>

I tried several methods and found success with the one described in this css-tricks article using overflow-anchor. I'd recommend checking out the article as it has a proper explanation.

#messages-container * {
  overflow-anchor: none;
}

#anchor {
  overflow-anchor: auto;
  height: 1px;
}
<div id="messages-container">
  <!-- Insert messages here -->
  <div id="anchor"></div>
</div>

被翻牌 2025-02-14 16:57:12

您可以使用 scrolltop 实现它。

我只是写了一个示例供您参考,您会发现有两种实现卷轴的方法,一种是使用动画包装器,另一个是直接使用它,您可以比较两种方法之间的差异。

const sendMessage = (selector, isAnimate = true) => {
  const text = $(selector).val();
  const $container = $('.form-container');
  $container.append(`<p>${text}</p>`);
  if (isAnimate) {
    $container.animate({
      scrollTop: $container.prop('scrollHeight')
    }, 1000);
  } else {
    $container.scrollTop($container.prop('scrollHeight'));
  }
  $(selector).val('');
};

$('button:eq(0)').on('click', function() {
  sendMessage('input[type=text]');
});

$('button:eq(1)').on('click', function() {
  sendMessage('input[type=text]', false);
});
.form-container {
  width: 400px;
  height: 100px;
  padding: 10px;
  background-color: white;
  overflow: scroll;
  position: relative;
}
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<div class='form-container'>
  <p>This is line 1 of text</p>
  <p>This is line 2 of text</p>
</div>
<div>
  <input type='text' placeholder="Type a message.">
  <button type='button'>Use animation</button>
  <button type='button'>Don't use animation</button>
</div>

You can use scrollTop to achieve it.

I simply wrote an example for your reference, you will find that there are two ways to implement scrollTop, one is to use the animation wrapper, the other is to use it directly, you can compare the difference between the two methods.

const sendMessage = (selector, isAnimate = true) => {
  const text = $(selector).val();
  const $container = $('.form-container');
  $container.append(`<p>${text}</p>`);
  if (isAnimate) {
    $container.animate({
      scrollTop: $container.prop('scrollHeight')
    }, 1000);
  } else {
    $container.scrollTop($container.prop('scrollHeight'));
  }
  $(selector).val('');
};

$('button:eq(0)').on('click', function() {
  sendMessage('input[type=text]');
});

$('button:eq(1)').on('click', function() {
  sendMessage('input[type=text]', false);
});
.form-container {
  width: 400px;
  height: 100px;
  padding: 10px;
  background-color: white;
  overflow: scroll;
  position: relative;
}
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<div class='form-container'>
  <p>This is line 1 of text</p>
  <p>This is line 2 of text</p>
</div>
<div>
  <input type='text' placeholder="Type a message.">
  <button type='button'>Use animation</button>
  <button type='button'>Don't use animation</button>
</div>

花辞树 2025-02-14 16:57:12

包含消息的DIV:#chat-output

#chat-output {
    border: 1px solid #ccc;
    overflow-x: hidden;
    overflow-y: auto;
    height: 400px;
}

函数 scrolltobottom()

function scrollToBottom(){
    var d = $('#chat-output');
    d.scrollTop(d.prop("scrollHeight"));
}

调用 scrolltobottom()每次您想要##chat--输出要滚动到底部:

例如,在dom-Ready上,

$(function () {
    scrollToBottom()
})

例如,将新聊天消息附加到#cath-output

function appendNewChatItem() {
    // your append() code here
    scrollToBottom();
}

The div containing the messages: #chat-output

#chat-output {
    border: 1px solid #ccc;
    overflow-x: hidden;
    overflow-y: auto;
    height: 400px;
}

function scrollToBottom()

function scrollToBottom(){
    var d = $('#chat-output');
    d.scrollTop(d.prop("scrollHeight"));
}

Call scrollToBottom() every time you want the #chat-output to scroll to the bottom:

E.g. On DOM-ready

$(function () {
    scrollToBottom()
})

E.g after appending new chat messages to the #chat-output:

function appendNewChatItem() {
    // your append() code here
    scrollToBottom();
}
国际总奸 2025-02-14 16:57:12

这对我有用:

outputArea[0].scrollTop = 9e9; 

This worked for me:

outputArea[0].scrollTop = 9e9; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文