40弹幕实现
基本结构
<div class="big">
<div class="small">
<input type="text" placeholder="输入弹幕内容" autofocus>
<button>发送</button>
</div>
</div>
基本样式
* {
padding: 0;
margin: 0;
}
.big {
width: 800px;
height: 400px;
margin: 50px auto;
position: relative;
overflow: hidden;
}
.big .small {
width: 780px;
height: 50px;
position: absolute;
left: 0;
bottom: 0;
}
.big .small input {
width: 666px;
height: 46px;
font-size: 24px;
}
.big .small button {
width: 100px;
height: 50px;
vertical-align: top;
float: right;
cursor: pointer;
}
JavaScript面向对象
//创建一个class
class Barrage {
//设置形参
constructor(frame, button, whole, chat, time, high, size) {
//获取文本框
this.input = document.querySelector(frame)
//获取按钮
this.button = document.querySelector(button)
//获取大盒子
this.big = document.querySelector(whole)
//获取需要创建的弹幕的标签
this.chat = chat
//获取弹幕运动的时间
this.time = time
//获取设置的弹幕覆盖范围
this.high = high
/获取弹幕的字体大小
this.size = size
//使用函数init()
this.init()
}
//函数init()
//相当于一个目录,需要直接使用的函数都直接写在目录中
init() {
//使用函数
this.key()
this.click()
this.screen()
}
//函数screen()
//设置弹幕的覆盖范围为"全屏"、"半屏"、"顶部"之一
screen() {
//获取high
switch (this.high) {
case "全屏":
this.high = 320
break;
case "半屏":
this.high = 160
break;
case "顶部":
this.high = 0
break;
default:
alert("弹幕弹出方式错误")
break;
}
}
//函数key()
//敲击回车键触发的事件
key() {
//敲击回车键(keyCode = 13)时使用函数use()
onkeydown = e => {
e = e || window.event
if (e.keyCode == 13) {
this.use()
}
}
}
//函数click()
//点击button触发的事件
click() {
//点击button时使用函数use()
this.button.onclick = () => {
this.use()
}
}
//函数use()
//输入的值存入弹幕并清空文本框中的值
use() {
//获取input文本框的值
let inner = this.input.value
//如果input文本框没有输入值,为空时
if (!inner) {
//弹出弹窗并使用return结束
alert("弹幕内容不能为空")
return
}
//清空input文本框的值
this.input.value = ""
//使用create()函数
this.create(this.chat)
//价格已经获取的input文本框的值填入新建的build标签中
this.build.innerHTML = inner
//使用函数animation()
this.animation(this.build, this.big.offsetWidth, 0, this.time)
使用函数toTop()
this.toTop()
}
//函数toTop()
//设置弹幕的垂直出现位置
toTop(){
//覆盖范围最小值为0,最大值取需要覆盖的范围的值
let toTp = parseInt(Math.random() * this.high)
//将弹幕的垂直位置设置出来
this.build.style.top = toTp + "px"
}
//函数create()
//创建弹幕标签,并且设置样式
create(ele) {
//创建弹幕标签
this.build = document.createElement(ele)
//给弹幕标签设置绝对定位
this.build.style.position = "absolute"
//给弹幕的字体设置字体颜色
//使用函数color()
this.build.style.color = this.color()
//设置弹幕的字体大小
this.build.style.fontSize = this.size + "px"
//设置弹幕里面的值不能换行
//如果不设置,在输入中文的时候会先纵向排列,再随弹幕标签的运用变大而变成横向
this.build.style.whiteSpace = "nowrap"
//将新建的弹幕标签追加到大盒子里
this.big.appendChild(this.build)
}
//函数color()
//设置随机字体颜色
color() {
//设置一个空变量
let colour = ""
//循环六次,因为#+16进制的颜色有6位
for (let i = 0; i < 6; i++) {
//将6次产生的16进制的数拼接在一起
colour += parseInt(Math.random() * 15).toString(16)
}
//返回拼接的16进制颜色
return "#" + colour
}
//函数animation()
//弹幕的运动方式以及速度
//ele 弹幕标签
//first 弹幕的起始位置
//last 弹幕的结束位置
//time 弹幕运动的总时间
animation(ele, first, last, time) {
//新建的弹幕标签默认left = 0,为了能使弹幕从设置的起始位置出发,初始设置left的值
ele.style.left = first + "px"
//弹幕的运动使用一个计时器
ele.timer = setInterval(function () {
//计算步长,实现设置的时间完成弹幕运动
let step = parseInt((last - first) * 30 / time / 1000)
//弹幕每30ms运行一次
ele.style.left = ele.offsetLeft + step + "px"
//当弹幕到达大盒子的最左边时解除定时器并将这个弹幕标签删除
//需要设置弹幕标签与弹幕标签之和小于等于0时才使用
//如果设置parseInt(ele.style.left) <= 0,会出现弹幕标签左边接触大盒子左边时就立即接触计时器并删除,
//导致里面的内容并没有到达大盒子的左边
//设置parseInt(ele.style.left) + ele.offsetWidth <= 0,
//当弹幕标签左边超出大盒子左边的距离刚好为弹幕标签的长度时停止计时器并删除弹幕
if (parseInt(ele.style.left) + ele.offsetWidth <= 0) {
clearInterval(ele.timer)
ele.remove()
}
}, 30)
}
}
//Barrage实例化
new Barrage(".big .small input", ".big .small button", ".big", "div", 5, "全屏", 30)