Bilibili 一键三连怎么实现?看完这篇你就懂了!
前言
经常去bilibili网站逛的人,肯定都知道它的--->一键三连<---,看到符合自己兴趣的立马三连!那接下来我们来探索下这个怎么实现的吧~~~
这是bilibili上的,
其实呢后面我采用了自定义事件实现的丐版哈~
自定义事件
概念: 顾名思义就是自己打造的事件,包含事件名,事件回调等,定义好后给其他模块使用,可以实现模块间的通信。
方式: 主要有2种,分别是Event()
构造函数和CustomEvent()
构造函数来创建。
1. Event()
语法:event = new Event(typeArg, eventInit);
参数:
typeArg
表示所创建事件的名称eventInit
可选字段,可以接收的字段:bubbles
(表示该事件是否冒泡,默认值为false
)、cancelable
(表示该事件能否被取消)、composed
(指示事件是否会在影子 DOM 根节点之外触发侦听器)
2. CustomEvent()
语法:event = new CustomEvent(typeArg, customEventInit);
参数:
typeArg
表示所创建事件的名称customEventInit
可选字段,可以接收的字段:detail
(是一个与 事件 相关的值)、bubbles
(表示该事件能否冒泡,默认不冒泡)、cancelable
(表示该事件是否可以取消)
3. 两者区别
new Event()
创建简单的自定义事件new CustomEvent()
支持给自定义事件传递参数
好吧,了解这些基础的后,进入正题吧!
基本练手
1. 实现初次加载自动执行某事件(Event())
我们先来看个例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#a{
width: 200px;
height: 200px;
background-color: #9ad621;
}
#b{
width: 100px;
height: 100px;
background-color: aqua;
}
</style>
</head>
<body>
<div id="a">
<div id="b"></div>
</div>
<script>
//创建事件
let myEvent = new Event('aaa',{"bubbles":true,"cancelable":false});//事件支持冒泡且可以取消
window.addEventListener("aaa",(e)=>{ //监听事件
console.log('window test');
})
let b=document.getElementById('b')
b.dispatchEvent(myEvent) //
</script>
</body>
</html>
页面初次加载就打印了 'window test'。
大致思路:
- 先创建自定义的事件,包括事件名以及一些配置。这里开启了在冒泡阶段执行的事件'aaa';
window
上监听事件 'aaa',等到事件触发后执行。也就是类似于发布-订阅模式中的订阅模式,等到事件'aaa'发布后就能执行回调函数了。此时addEventListener
的第3个参数没传代表默认是在冒泡阶段下监听到此事件'aaa';- 给b盒子上发布事件
myEvent
。
适用场景: 可以用在初次进入某页面时自动播放视频之类的
2. 点击任意盒子触发事件(CustomEvent()
)
css部分和前面一样的,js不同如下:
<script>
let myEvent=new CustomEvent('test',{detail:{name:'mytest'}})
window.addEventListener('test',e=>{ //订阅
console.log(`test事件被${e.detail.name}触发`);
})
document.getElementById('a').addEventListener('click',()=>{
window.dispatchEvent(myEvent) //发布
})
</script>
不管是点击蓝盒子还是绿盒子,都会触发打印事件。
大致思路:
- 创建事件
- 订阅事件(即监听事件)
- 发布事件
3. 实现异步操作
<script>
// let finish=new CustomEvent('finish',{detail:{name:'ok'}})
function a(){
setTimeout(()=>{
console.log('请求A完成');
},1000)
}
function b(){
setTimeout(()=>{
console.log('请求B完成');
},500)
}
a()
b()
</script>
打印顺序:请求B完成--> 请求A完成
现在想实现打印顺序:请求A完成--> 请求B完成
主要实现如下:
<script>
let finish=new CustomEvent('finish',{detail:{name:'ok'}})
function a(){
setTimeout(()=>{
console.log('请求A完成');
window.dispatchEvent(finish)
},1000)
}
function b(){
setTimeout(()=>{
console.log('请求B完成');
},500)
}
a()
window.addEventListener('finish',()=>{
b()
})
</script>
这主要是利用了定时器,在函数a执行完后才发布事件finish,进而b函数就能触发了。
实现Bilibili一键三连
1. 搭建基本结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_4216715_c3yizkdfor.css">
<title>Document</title>
<style>
.box{
display: flex;
justify-content: center;
align-items: center;
}
.iconfont{
font-size: 42px;
}
.color{
background-color: red;
}
</style>
</head>
<body>
<div class="box">
<div class="icon1">
<i class="iconfont icon-shoucang i1"></i>
点赞
</div>
<div class="icon2">
<i class="iconfont icon-good i2"></i>
投币
</div>
<div class="icon3">
<i class="iconfont icon-data-migration i3"></i>
收藏
</div>
</div>
</body>
</html>
2. 初步js编写
let myEvent=new CustomEvent('test',{detail:{class:'color'}})
window.addEventListener('test',e=>{
console.log(`test事件被${e.detail.class}触发`);
i1.setAttribute('class','iconfont icon-shoucang i1 color')
i2.setAttribute('class','iconfont icon-good i2 color')
i3.setAttribute('class','iconfont icon-data-migration i3 color')
})
document.querySelector('.i1').addEventListener('dblclick',()=>{
window.dispatchEvent(myEvent) //发布
})
let i1=document.querySelector('.i1')
let i2=document.querySelector('.i2')
let i3=document.querySelector('.i3')
i1.addEventListener('click',()=>{
i1.setAttribute('class','iconfont icon-shoucang i1 color')
})
i2.addEventListener('click',()=>{
i2.setAttribute('class','iconfont icon-good i2 color')
})
i3.addEventListener('click',()=>{
i3.setAttribute('class','iconfont icon-data-migration i3 color')
})
</script>
思路:
- 给每个icon添加点击事件,实现每点一个就给自身添加背景颜色
- 额外再给第1个icon添加
test
事件,等到事件发布后执行回调- 在第1个icon双击后就发布
test
事件
这时候你会说不对呀,你这是双击实现的,哪里是一键三连呀?别急,下面我们来实现真正的“一键三连”!
3. 最终版
<div class="box">
<div class="icon1" onmousedown="down()" onmouseup="up()">
<i class="iconfont icon-shoucang i1"></i>
点赞
</div>
<div class="icon2">
<i class="iconfont icon-good i2"></i>
投币
</div>
<div class="icon3">
<i class="iconfont icon-data-migration i3"></i>
收藏
</div>
</div>
<script>
let myEvent=new CustomEvent('test',{detail:{class:'color'}})
function down(){
i1.setAttribute('class','iconfont icon-shoucang i1 color')
time=setTimeout(()=>{
console.log('长按事件');
window.dispatchEvent(myEvent)
},1000)
}
function up(){
clearTimeout(time)
}
window.addEventListener('test',e=>{
console.log(`test事件被${e.detail.class}触发`);
i1.setAttribute('class','iconfont icon-shoucang i1 color')
i2.setAttribute('class','iconfont icon-good i2 color')
i3.setAttribute('class','iconfont icon-data-migration i3 color')
})
let i1=document.querySelector('.i1')
let i2=document.querySelector('.i2')
let i3=document.querySelector('.i3')
i1.addEventListener('click',()=>{
i1.setAttribute('class','iconfont icon-shoucang i1 color')
})
i2.addEventListener('click',()=>{
i2.setAttribute('class','iconfont icon-good i2 color')
})
i3.addEventListener('click',()=>{
i3.setAttribute('class','iconfont icon-data-migration i3 color')
})
</script>
思路:
- 给每个icon添加点击事件,实现每点一个就给自身添加背景颜色
- 额外再给第1个icon添加
test
事件,等到事件发布后执行回调- 给第1个icon绑定鼠标按下和松开事件,并编写相应的函数。其中在鼠标左键长按达到1s时就能触发发布事件myEvent,松开后就清除定时器。
这样一个简陋版的一键三连就实现啦~
结束语
本篇文章就到此为止啦,由于本人经验水平有限,难免会有纰漏,对此欢迎指正。如觉得本文对你有帮助的话,欢迎点赞收藏❤❤❤。要是您觉得有更好的方法,欢迎评论,提出建议!
转载自:https://juejin.cn/post/7268607295017418789