访客输入区域弹出/收起的动态效果
点击【说点什么】的时候,从下往上弹出可选的对话内容。
此时再次点击空白区域,对话框又会向下收起来。
HTML部分
在index.html里搜索“说点什么”,可以看到这是一个div。
<div id="prompt-head">
<div class="say-something">说点什么……</div>
<a href="#" class="close-btn"
v-on:click="togglePrompt(false)"></a>
</div>
注意到里面有一个v-on:click
的点击事件绑定。虽然是个前端小白,可我还是认识html里的onclick事件的。可这里的v-on是什么鬼?整容了?
google了一下,发现这个v-on是使用了Vue框架后的写法。
Vue框架是一个js框架,我没接触过,正好一起学学。这里我们知道v-on:click
就相当于原来的onclick
就可以了。再看绑定的函数名猜也能猜到这个是用来切换显示状态的。这里传递的参数是false,应该是收起的意思。
继续找,又有一处“说点什么”的div
<div id="input-hint" class="say-something"
v-on:click="togglePrompt(true)"
:class="{'clickable': !isXianzheTyping }">
<span v-if="!isXianzheTyping">说点什么……</span>
<span v-if="isXianzheTyping">羡辙正在输入中</span>
</div>
这里应该是未弹出时显示的最下边那一条底栏了。在机器人未输入的状态(isXianzheTyping控制)下底栏文字显示“说点什么”并且允许点击,点击后调用togglePrompt(true),弹出访客输入区域。
页面的定义就是这些了。
js的部分
我们在index.js中找到togglePrompt函数。
togglePrompt(toShow) {
if (this.isXianzheTyping) {
// don't prompt if xianzhe is typing
return;
}
this.hasPrompt = toShow;
}
很简单,只是判断了一下当前状态是否允许弹出(html那边已经控制过clickable了,这里有点重复),然后简单的将传入的true/false值赋给this.hasPrompt变量就结束了。
这么神奇?this.hasPrompt = toShow;
这一句js指令是怎么控制页面元素的呢?这个hasPrompt一定跟页面元素有什么不可告人的关系。
我们回到index.html查找hasPrompt,果然,找到了<div id="mobile" :class="{ 'has-prompt': hasPrompt }">
这里又出现新东西了,:class=...
这种写法也是Vue框架里的,作用是将页面元素绑定到js变量上。这里将hasPrompt变量绑定在has-prompt这个class名上了。
好吧,我们继续找has-prompt的class定义,看看那边有什么东西。既然是class,那一定在css文件夹中了。翻了一通,在css/_mobile.prompt.scss
里找到了。
#prompt {
position: absolute;
bottom: 0%;
transform: translateY(100%);
z-index: 100;
width: 100%;
box-shadow: 0 0 30px 0 rgba(0, 0, 0, 0.2);
transition-duration: $prompt-animation-duration;
transition-property: transform;
#mobile.has-prompt & {
transform: translateY(0);
}
}
OK,这里的css定义里就是最终实际控制弹出/收起动画的地方了。等等,哪里不对劲?文件名很诡异啊,我记得css文件应该是.css啊,而且index.html里并没有引用这个.scss文件啊。这个.scss文件又是什么玩意???我这个前端小白一路上全都是不认识的玩意儿啊!没办法,又google了一下,简单来说scss是css的预编译语言,提供了css本来没有的比如变量定义等功能方便css的编写。写完以后再编译成标准的css供html使用。关于怎么编译,后面的系列文章里再说明吧,一下子东西太多了不好消化。这里先简单的理解成css就好了,语法其实都差不多的。
继续,这一段css里面关于显示动态效果的是下面几句:
- transform: translateY(xx%);
指定动画的类型是Y轴移动,xx表示偏移量。 - transition-duration: xx;
指定动画持续时间xx表示时间。
这里作者用了一个变量$prompt-animation-duration
来代替,这个变量可以在另一个scss文件css\_variables.scss
里找到:$prompt-animation-duration: 0.3s;
到这里基本上就可以猜到了,当js文件里对变量hasPrompt赋值的时候,Vue框架在背后做了大量工作,最后相当于直接控制了页面上某个绑定元素的css样式,从而控制这个元素的各种行为。比如弹出,收起,放大,缩小,都是可以做到的。这样看来,Vue框架确实很强大。
试试改一改
改一下弹出方式
/* 修改前:transform: translateY(100%); */
/* 弹出方式变成横向弹出 */
transform: translateX(100%);
再改一下位置
#mobile.has-prompt & {
/* 修改前:transform: translateY(0); */
/* 修改弹出后的位置 */
transform: translateY(-100%);
}
变成这样了
整理一下流程
- html:引入Vue框架
- js:创建Vue对象并同时将这个对象绑定到页面上某个元素。在这里是“id=mobile”的div。然后在Vue对象里定义各种data,其中就有hasPrompt变量。
- html:将hasPrompt的变量,继续绑定在mobile的class“has-prompt”上。
- scss:使用被绑定的class“has-prompt”,为不同的class状态编写不同的行为。
- js:根据需要对js变量hasPrompt赋值,即可影响被绑定页面元素的样式和状态。(比如弹出/收起)
本文小结
从一个简单的弹出/收起动画效果引出这么多我从没接触过的概念还是挺意外的。可见现在的前端技术的发展有多迅速,我多年以前的那些原生html/js/css的概念已经跟不上现在开发的要求了。一定要保持对新技术的敏感,持续学习才行。
系列文章
- 开源代码分析学习 - 有趣的聊天机器人 - 01 - 这么好玩?
- 开源代码分析学习 - 有趣的聊天机器人 - 02 - 对话内容的定义
- 开源代码分析学习 - 有趣的聊天机器人 - 03 - 访客输入区域弹出/收起的动态效果【当前文章】