建站过程7-对话气泡框

之前个人主页右下角的垂云都可以鼠标点击交互的,这次也想要实现这个功能,而且还要更丰富一些,功能包括:点击出现气泡框,鼠标悬停阻止自动消失,随机文字。

气泡框绘制

因为不想直接动源代码,所以这里用的是hexo-fluid的代码注入功能,因此css只能写成行内的style属性,看起来有些丑qwq

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<div id="textbox" style="
width:150px;
height:50px;
border:2px solid #FF88C2;
border-radius: 4px;
box-shadow: 2px 2px 2px pink;
position:fixed;
left:20px;
bottom:180px;
background-color:white;
padding-top: 0.2em;
padding-bottom: 0.2em;
opacity: 0;
z-index: 10;
transition:0.5s all ease-in-out;
">
<div id="saytext" style="
height:100%;
font-size: 0.7em;
text-align: center;
display: flex;
align-items: center;
justify-content: center;"><span>你好,我是萍琪派!</span>
</div>
<div style="
width:0;
height:0;
border-top:10px solid #FF88C2;
border-left:10px dashed transparent;
border-right:10px dashed transparent;
position:relative;
left:60px;
bottom:-0.2em;">
</div>
</div>

简单解释:

  • 一个总的气泡盒子,固定在合适的位置,并且加上了一些颜色,设置了文字居中之类的;注意opacity属性用来控制是否显示,之所以不用visibility是因为这样没法通过transition实现淡入淡出的功能;
  • 然后下面绘制一个小小的倒三角;
  • 中间的<div>用来装文字;

动态交互功能

首先是一些全局变量:

1
2
3
4
5
6
7
8
9
10
11
/*#################*/
/* constant value */
/*#################*/
const cvs = document.querySelector("#live2d");
const box = document.querySelector("#textbox");
const text = document.querySelector("#saytext span");
const textbar = document.querySelector("#saytext");
const url = "/blog/js/saying.json";
let articles = null;
let timer = null;//用于取消延迟任务的ID值
let hover = false;

一些utility function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/** 随机选取数组中的元素 */
function randomChoose(array) {
let len = array.length;
return array[randomNum(len-1)];
}
/** 生成从minNum到maxNum的随机数
* 只输入第一个参数,表示[0,minNum]之间的随机数
* 输入两个参数,表示[minNum,maxNum]之间的随机数
* @param minNum
* @param maxNum
*/
function randomNum(minNum,maxNum){
switch(arguments.length){
case 1:
return Math.floor(Math.random()*(minNum+1));
break;
case 2:
return Math.floor(Math.random()*(maxNum-minNum+1)+minNum);
break;
default:
return 0;
break;
}
}
function randomBoolean(){
return Math.random()>0.5;
}

点击出现对话框以及鼠标悬停阻止消失

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function handler_say(event) {
clearTimeout(timer);
change_content(randomNum(0,1));
box.style.opacity=0.9;
timer = setTimeout(()=>{
if(!hover){
box.style.opacity=0;
}
},2000);
}
function handler_mouseenter(event){
hover = true;
}
function handler_mouseleave(event){
hover = false;
box.style.opacity=0;
}

简单解释:

  • 第一个函数是click事件的回调函数,和之前垂云那版的实现方式一样,先清除之前未执行的任务,然后改变气泡框文字内容,设置气泡框为可见,最后延迟2000ms之后重新让气泡框不可见;
  • 第二个是鼠标悬浮于气泡框时的回调函数,简单设置变量hover=true,这样一来之前的延迟任务就不会执行;
  • 第三个是鼠标移出气泡框的回调函数,设置hover=false,并且让气泡框不可见;

随机生成对话内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function change_content(group) {
if(articles==null){return;}
while(text.lastElementChild!=null){
text.removeChild(text.lastElementChild);
}
//更新span元素内容
let anchor = document.createElement("a");
text.textContent = randomChoose(articles[group].text);
if(group==0){ //选择一篇文章并且生成推荐文字
let item = randomChoose(articles[group].list);
anchor.setAttribute("href",item.link);
anchor.style.color = "#FF88C2";
anchor.textContent = item.title;
text.appendChild(anchor);
}
}

主要想法是,对话分为有超链接和没有超链接的两组(group),所有可能的对话内容都储存在saying.json文件中,然后每次随机从其中某组中选择一句话,构造对应的元素,然后插入相应位置;

读取json文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function say_init(){
cvs.style.cursor = 'grab';
cvs.addEventListener("click",handler_say);
textbar.addEventListener("mouseenter",handler_mouseenter);
textbar.addEventListener("mouseleave",handler_mouseleave);
// 载入json
var request = new XMLHttpRequest();
// 设置请求方法与路径
request.open("get", url);
// 不发送数据到服务器
request.send(null);
//XHR对象获取到返回信息后执行
request.onload = function(){
// 返回状态为200,即为数据获取成功
if(request.status == 200){
articles = JSON.parse(request.responseText);
}
else{
console.log("error:"+request.status+this.responseText);
}
}
}

这是此部分功能的主例程,绑定之前所说的回调函数,以及读取json文件

saying.json样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[
{
"text":[
"叮~~ 随机掉落文章推荐:",
"想看看这篇文章吗:"
],

"list":[
{
"title":"示例1",
"link":"/blog/示例1"
},
{
"title":"示例2",
"link":"https://xxx.xxx.com"
}
]
},
{
"text":[
"点击我可以给你推荐随机文章哦",
"如果喜欢这个站点,欢迎与朋友分享,快乐也会加倍哦",
"小技巧:示例3"
]
}
]

效果图

成功了~ 来看看我们的成果吧:

示意图


建站过程7-对话气泡框
https://www.hovering-clouds.cn/space/2022/07/01/建站过程7-气泡对话框/
作者
垂云
发布于
2022年7月1日
许可协议