自定义问题类型,平滑滚动底部 以下是主題部分 在此使用的是vue.js+element
js部分内容
var app = new Vue({
el: '#app',
data() {
return{
limitationType:1,
observer: null,
userImage:'',
question:"",
userAnwer:"",
nowQuestion:'',
messageList:[
{
type:'r',
text:'正在根据您的学习背景、兴趣爱好、职业目标等信息生成您的专属报告及报告解析。',
},
{
type:'rs',
num:1,
text:'“请简单介绍一下学业职业规划报告能解决我的什么问题”'
},
{
type:'rs',
num:2,
text:'“请帮我解读一下我的核心竞争力评估结果”'
},
{
type:'rs',
num:3,
text:'“请简要分析一下我的学业、职业规划概览”'
},
],
}
},
methods:{
mySend(){
if (this.limitationType==1){
if (!this.question){
this.$message({
message: '请输入您的问题再发送哦~',
type: 'warning'
});
return false;
}
this.nowQuestion=this.question
var userQuestion={
type:'u',
text:this.question,
}
this.messageList.push(userQuestion)
this.question=""
this.limitationType=2
this.getResult()
}else {
this.$message.error('稍等片刻,等一言回复后在发送哦~');
return false;
}
},
getResult:function (){
var _this=this
var userQuestion={
type:'r',
text:'',
}
this.messageList.push(userQuestion)
var length=this.messageList.length-1
// 定时器模仿数据延迟
setTimeout(function (){
_this.userAnwer="这里是写死的答案数据数据,需要把接口放开,联系工作人员"
_this.simulateTyping(length)
},4000)
},
simulateTyping:function (val) {
if (this.isTyping) return;
this.isTyping = true;
let index = 0;
const interval = setInterval(() => {
if (index < this.userAnwer.length) {
this.messageList[val].text += this.userAnwer[index++];
} else {
clearInterval(interval);
this.limitationType=1
this.isTyping = false;
}
}, 20);
},
scrollToBottomWithOffset() {
const chatIn = this.$refs.chatIn;
const scrollHeight = chatIn.scrollHeight;
const clientHeight = chatIn.clientHeight;
const scrollTop = chatIn.scrollTop;
const offset = -100; // 距离底部的偏移量
// 计算新的滚动位置
const newScrollTop = scrollHeight - clientHeight - offset;
// 平滑滚动到新的位置
this.smoothScroll(chatIn, newScrollTop);
},
smoothScroll(element, targetPosition) {
const startPosition = element.scrollTop;
const distance = targetPosition - startPosition;
const duration = 50; // 滚动持续时间(毫秒)
const startTime = 'now' in window.performance ? performance.now() : new Date().getTime();
function animation(currentTime) {
const timeElapsed = currentTime - startTime;
const run = ease(timeElapsed, startPosition, distance, duration);
element.scrollTop = run;
if (timeElapsed < duration) requestAnimationFrame(animation);
}
function ease(t, b, c, d) {
// t = current time, b = start value, c = change in value, d = duration
t /= d / 2;
if (t < 1) return c / 2 * t * t + b;
t--;
return -c / 2 * (t * (t - 2) - 1) + b;
}
requestAnimationFrame(animation);
},
questionSend:function (val){
var _this=this
if (val==1){
_this.question='请简单介绍一下学业职业规划报告能解决我的什么问题'
}else if(val==2){
_this.question='请帮我解读一下我的核心竞争力评估结果'
}else if(val==3){
_this.question='请简要分析一下我的学业、职业规划概览'
}
_this.mySend()
},
},
created: function () {
},
mounted() {
this.userImage=localStorage.getItem('headImage')
this.creatChat();
this.observer = new MutationObserver(mutations => {
this.scrollToBottomWithOffset();
});
const config = {
childList: true, // 观察子节点的变动(新增、移除)
subtree: true, // 观察后代节点的变动
};
const targetNode = this.$refs.chatIn;
// 启动观察
this.observer.observe(targetNode, config);
},
beforeDestroy(){
if (this.observer) {
this.observer.disconnect();
}
},
})
最终效果 大致如下