某些业务会使用到页面里存在一个机器人,类似于假客服一样,可以回复游客的问题.

那么如何自己写一个自动回复消息的机器人呢?

源码献上

/**
* 基于jq的自动对话机器人
* @param {Object} parmas 初始化配置
* parmas.talkModal 对话框弹出主体 classname
* parmas.talkBox 对话框内容区域 classname
* parmas.awakeBtn 唤醒按钮 用于显示对话框主体 classname
* parmas.exitBtn 隐藏按钮 用户隐藏对话框按钮 classname
* parmas.sendBtn 发送消息按钮 classname
* parmas.autoConent 自动对话框内容 Array
* parmas.input 内容输入框 classname
* parmas.openReply 在打开的时候自动回复一句 true or false 默认true
* parmas.replyName 自动回复的dom类名 classname
* parmas.userName 用户回复的dom类名 classname
* parmas.isChangeBtnStatus 是否在点击 唤醒和隐藏的时候隐藏相反的按钮 true or false 默认true
* parmas.fixedMsg 固定回复语句 string or dom
*
*/
function Talk(parmas) {
if (typeof $ === "undefined") {
throw new Error("Please load JQ API before use the Talk function!")
}
this.talkModal = $('.' + parmas.talkModal);
this.talkContent = $("." + parmas.talkBox)
this.awakeBtn = $("." + parmas.awakeBtn)
this.autoConent = parmas.autoConent || ['你好', "欢迎你", "谢谢", "再见"]
this.exitBtn = $("." + parmas.exitBtn)
this.input = $("." + parmas.input)
this.sendBtn = $("." + parmas.sendBtn)
this.contentDefaultHeight = 0 // 对话框内容区域高度
this.autoTimer = null; // 自动回复定时器
this.autoIndexArr = Array.from({ length: this.autoConent.length }, (v, k) => k) //随机索引,先默认数组索引下标排列
this.contentIndex = 0;
this.openReply = parmas.openReply !== undefined ? parmas.openReply : true;
this.fixedMsg = parmas.fixedMsg || "收到";
this.isFixedReply = false;
this.changeBtnStatus = parmas.isChangeBtnStatus !== undefined ? parmas.isChangeBtnStatus : true
this.replyClassName = parmas.replyName || 'reply'
this.userClassName = parmas.userName || 'customer-txt'
// 检查绑定的dom是否符合规范
this.isInvalid()
// 绑定监听事件
this.addEvent()
// 生成自动回复索引
this.randomIndex()
}
// 检查绑定的dom是否符合规范
Talk.prototype.isInvalid = function () {
if (this.talkModal.length === 0) {
throw new Error('The TalkModal is not found.Please check out the binding TalkModel.')
}
if (this.talkContent.length === 0) {
throw new Error("The TalkModal's contentBox is not found.Please check out the binding TalkModal's contentBox.")
}
if (this.awakeBtn.length === 0) {
throw new Error("The TalkModal's awake Button is not found.Please check out the binding TalkModal's awake Button.")
}
if (this.input.length === 0) {
throw new Error("The TalkModal's input is not found.Please check out the binding TalkModal's input.")
} if (this.talkModal.length !== 1) {
throw new Error("The TalkModal is not unique classname,Please check out the dom's classname.")
}
if (this.talkContent.length !== 1) {
throw new Error("The TalkModal's contentBox is not unique classname,Please check out the dom's classname.")
}
if (this.awakeBtn.length !== 1) {
throw new Error("The TalkModal's awake Button is not unique classname,Please check out the dom's classname.")
}
if (this.input.length !== 1) {
throw new Error("The TalkModal's input is not unique classname,Please check out the dom's classname.")
}
} // 绑定事件
Talk.prototype.addEvent = function () {
// 唤醒对话框按钮绑定事件
this.awakeBtn.click(function (e) {
e.stopPropagation || e.stopPropagation()
this.showModal()
}.bind(this))
// 关闭对话框按钮 绑定事件
this.exitBtn.click(function (e) {
e.stopPropagation || e.stopPropagation()
this.hiddenModal()
}.bind(this))
// 发送消息按钮 绑定事件
this.sendBtn.click(function (e) {
e.stopPropagation || e.stopPropagation()
this.sendMsg()
}.bind(this))
// 输入框按钮监听回车
this.input.on("keypress", function (event) {
if (event.keyCode == "13") {
this.sendMsg()
}
}.bind(this))
} // 显示对话框
Talk.prototype.showModal = function () {
this.talkModal.fadeIn(300)
if (this.changeBtnStatus) {
this.awakeBtn.hide()
this.exitBtn.show()
}
if (this.openReply) {
this.autoReply()
}
if (this.contentDefaultHeight === 0) {
this.contentDefaultHeight = this.talkContent.height()
}
} // 隐藏对话框
Talk.prototype.hiddenModal = function () {
clearTimeout(this.autoTimer)
this.talkModal.fadeOut(0)
if (this.changeBtnStatus) {
this.exitBtn.hide()
this.awakeBtn.show()
}
} // 用户主动发送消息
Talk.prototype.sendMsg = function () {
var val = this.input.val()
if (!val || !val.trim()) {
return
}
this.appendContent(this.userClassName, val)
this.input.val('')
this.isFixedReply = false
// ...这里可以判断用户输入信息进行其他处理
this.dealMsg(val) }
/**
* 处理用户输入信息 根据信息来回复
* @param {String} msg 用户输入信息
*/
Talk.prototype.dealMsg = function (msg) {
// ...do Ajax or on the msg,according to directed reply
if (msg === "你好") {
var str = '我不好'
this.autoReply(str)
return
}
if (msg === "18888888888") {
this.isFixedReply = true
}
// auto reply
this.autoReply()
} /**
* 追加文本,每次聊天后滚动聊天区域
* @param {String} classname 回复的类名 用于显示不同的对话
* @param {String} content 内容,即聊天内容
*/
Talk.prototype.appendContent = function (classname, content) {
this.talkContent.append('<div><p class="' + classname + '">' + content + '</p></div>')
this.srcollContent()
} // 滚动聊天内容区域
Talk.prototype.srcollContent = function () {
var height = this.talkContent.prop("scrollHeight")
if (this.contentDefaultHeight > height) {
return
}
this.talkContent.animate({ scrollTop: height }, 400);
} /**
* 机器人自动回复
* @param {String} str 需要回复的内容 若没有则自动回复
*/
Talk.prototype.autoReply = function (str) {
clearTimeout(this.autoTimer)
this.autoTimer = setTimeout(function () {
if (this.isFixedReply) {
return this.appendContent(this.replyClassName, this.fixedMsg)
}
if (str) {
return this.appendContent(this.replyClassName, str)
}
var content = this.autoConent[this.autoIndexArr[this.contentIndex]]
this.contentIndex += 1
this.appendContent(this.replyClassName, content)
if (this.contentIndex === this.autoConent.length) {
this.randomIndex()
this.contentIndex = 0
}
}.bind(this), 1500)
} // 生成随机的消息索引数组
Talk.prototype.randomIndex = function () {
var len = this.autoConent.length;
var temp = this.autoIndexArr
for (var i = 0; i < len + 10; i++) {
var rdm = Math.floor(Math.random() * temp.length)
temp.push(temp[rdm])
temp.splice(rdm, 1)
}
if (temp[0] === this.autoIndexArr[len - 1]) {
this.randomIndex()
} else {
this.autoIndexArr = temp
}
}

如何自己定制机器人回复内容

只需要重写Talk函数的dealMsg函数即可,默认第一个参数是用户输入的内容,根据第一个参数进行判断去调用this.autoReply(str)即可,若不传str则默认是以预设的自动回复语句去回复.

若你是否重写dealMsg,在Talk构造函数之后去实例化

  • 实例化
var talk = new Talk({
talkModal: "modal", // 对话框主体
talkBox: "talk-content", // 对话框内容区域
awakeBtn: "awake", // 唤醒对话框按钮
exitBtn: "exit", // 关闭对话框按钮
input: "ipt", // 对话框input
sendBtn: "send", // 发送信息按钮 // 自动回复的语句可以包含html字符
replyName: "reply", //回复的类名 用于样式
userName: "msg", // 用户使用的类名 用于样式
openReply: false, // 打开自动回复一句
})

案例

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Talk</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<!-- 请在jq加载后,加载Talk,引入文件方式 ,或者 直接把函数复制到script里即可-->
<script src="./Talk.js"></script>
<style>
* {
margin: 0;
padding: 0;
border: 0;
} .header {
padding: 20px;
text-align: center;
font-size: 24px;
background-color: antiquewhite;
} .content {
text-align: center;
font-size: 24px;
height: 1000px;
line-height: 500px;
background-color: aquamarine;
} .fixed-wrap {
position: fixed;
right: 0;
top: 50%;
transform: translateY(-50%);
width: 30px;
height: 100px;
background-color: blanchedalmond;
} .btn {
text-align: center;
padding: 3px 5px;
font-size: 14px;
cursor: pointer;
} .exit {
display: none;
} .modal {
position: absolute;
display: none;
left: -300px;
top: -70px;
padding: 10px;
width: 300px;
height: 240px;
box-sizing: border-box;
background-color: burlywood;
} .talk-content {
height: 200px;
overflow-y: auto;
} .talk-content div {
overflow: hidden;
} .talk-content p {
margin-bottom: 10px;
padding: 8px;
max-width: 80%;
word-break: break-all;
font-size: 12px;
color: #000;
border-radius: 10px;
} .talk-content span {
color: red;
} .msg {
float: right;
background-color: #b7e6e7;
} .reply {
float: left;
background-color: #fff;
} .control {
position: absolute;
left: 10px;
bottom: 5px;
height: 25px;
} .control input,
.control button {
outline: none;
height: 100%;
padding: 0 10px;
}
</style>
</head> <body>
<div class="header">header</div>
<div class="content">content</div>
<div class="fixed-wrap">
<div class="awake btn">展开机器人</div>
<div class="exit btn">关闭机器人</div>
<div class="modal">
<div class="talk-content">
</div>
<div class="control">
<input type="text" class="ipt">
<button class="send">发送</button>
</div>
</div>
</div>
</body>
<script>
var talk = new Talk({
talkModal: "modal", // 对话框主体
talkBox: "talk-content", // 对话框内容区域
awakeBtn: "awake", // 唤醒对话框按钮
exitBtn: "exit", // 关闭对话框按钮
input: "ipt", // 对话框input
sendBtn: "send", // 发送信息按钮 // 自动回复的语句可以包含html字符
replyName: "reply", //回复的类名 用于样式
userName: "msg", // 用户使用的类名 用于样式
openReply: false, // 打开自动回复一句
})
</script> </html>

  

基于JQ使用原生js构造一个自动回复随机消息的机器人的更多相关文章

  1. jq与原生js实现收起展开效果

    jq与原生js实现收起展开效果 (jq需自己加载) <!DOCTYPE html> <html> <head> <meta charset="UTF ...

  2. 原生js实现一个DIV的碰撞反弹运动,并且添加重力效果

    继上一篇... 原生js实现一个DIV的碰撞反弹运动,并且添加重力效果 关键在于边界检测,以及乘以的系数问题,实现代码并不难,如下: <!DOCTYPE html> <html la ...

  3. 原生js实现一个DIV的碰撞反弹运动

     原生js实现一个DIV的碰撞反弹运动: 关键在于DIV的边界检测,进而改变运动方向,即可实现碰撞反弹效果. <!DOCTYPE html> <html lang="en& ...

  4. 用原生js写一个"多动症"的简历

    用原生js写一个"多动症"的简历 预览地址源码地址 最近在知乎上看到@方应杭用vue写了一个会动的简历,觉得挺好玩的,研究一下其实现思路,决定试试用原生js来实现. 会动的简历实现 ...

  5. 原生js实现一个简单的轮播图

    想锻炼一下自己的原生js能力可以从写一个轮播图开始,轮播图的运用想必大家都知道吧,好了废话不多说,开始记笔记了,一些需要注意的点,我都在代码中标注了 首先是构造html: <div id=&qu ...

  6. 原生js写一个无缝轮播图插件(支持vue)

    轮播图插件(Broadcast.js) 前言:写这个插件的原因 前段时间准备用vue加上网易云的nodejs接口,模拟网易云音乐移动端.因为想自己写一遍所有的代码以及加固自己的flex布局,所以没有使 ...

  7. 使用原生JS实现一个风箱式的demo,并封装了一个运动框架

    声明,该DEMO依托于某个培训机构中,非常感谢这个培训结构.话不多说,现在开始改demo的制作. 首先,在前端的学习过程中,轮播图是我们一定要学习的,所以为了更加高效的实现各种轮播图,封装了一个运动的 ...

  8. 导航栏中各按钮在点击当前按钮变色其他按钮恢复为原有色的实现方法(vue、jq、原生js)

    一.vue如何实现? 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  9. 用原生JS实现一个轮播(包含全部代码和详细思路)

    在我看来要想实现轮播主要是要知道当前位于的页面和即将位于的页面.这个案例是通过改变图片的透明度来实现轮播的效果. 我把涉及的知识点分为两个方面,分别是HTML+css和JS. 第一部分(html+cs ...

  10. 用原生JS写一个网页版的2048小游戏(兼容移动端)

    这个游戏JS部分全都是用原生JS代码写的,加有少量的CSS3动画,并简单的兼容了一下移动端. 先看一下在线的demo:https://yuan-yiming.github.io/2048-online ...

随机推荐

  1. kettle使用1-全表导入

    1.新建转换 2.DB连接中,新建数据库连接 3.在输入中,选择表输入 选择连接的数据库和查询的sql的数据 4.再输出中,选择表输出 5.按住shift,建立数据连接 6.匹配数据字段映射

  2. 欧洲对 Splashtop 远程计算机实验室的需求增长十倍

    ​2021 年 1 月 7 日,加利福尼亚州圣何塞 - 远程访问和远程支持解决方案的全球领导者 Splashtop Inc. 报告称其对用于教育的远程实验室访问软件的需求在欧洲激增,在 2020 年第 ...

  3. pageoffice 6 实现数据区域填充(插入文本、图片、word、excel等)

    在实际的Word文档开发中,经常需要自动填充数据到Word模板中,以生成动态的Word文档. 例如: 1.我们可以根据数据库表中已保存的个人信息,设计好一个简历模板docx文件,然后通过代码将这些个人 ...

  4. python计算机视觉学习笔记——PIL库的用法

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 这个 ...

  5. go高并发之路——启航

    工作7年有余了,B端和C端业务都做过不少,打算整理分享一些自己在实际工作中所遇到的高并发的场景和解决方案,也是对自己本人职业生涯中的一些经验的总结和感悟.与其他博文略有不同的是,这些基本上都是自己实际 ...

  6. HashMap设置初始容量一直都用错了?

    1 背景 今天在代码审查的时候,发现一位离职的同事留下了这样一串代码: Map<String,String> map = new HashMap<>((int)(list.si ...

  7. NOIP模拟95(多校28)

    T1 嗑瓜子 解题思路 \(f_{i,j}\) 表示操作 \(i\) 次,拿走了 \(j\) 个瓜子的概率,转移就比较直接了: \[f_{i+1,j+1}\leftarrow f_{i,j}\time ...

  8. 《python核心编程《第二版》》笔记章节索引

    本文章作为我的其它一系列关于<python核心编程<第二版>>的笔记的文章索引. 第一章:Python-快速入门:https://www.cnblogs.com/mrlayfo ...

  9. c# Redis缓存的使用和helper类;

    使用背景: 项目中用户频繁访问数据库会导致程序的卡顿,甚至堵塞.使用缓存可以有效的降低用户访问数据库的频次,有效的减少并发的压力.保护后端真实的服务器. 对于开发人员需要方便调用,所以本文提供了hel ...

  10. CSP-S2023 题解

    CSP-S 2023 题解 密码锁 发现总状态数只有 \(10^5\) 个,枚举 \(O(n)\) 暴力判断即可,复杂度 \(O(10^5 n)\). 或者每一个状态只对应了 \(81\) 个状态,枚 ...