原生JS实现弹幕效果的简单操作指南
本文介绍如何使用原生JavaScript实现简易弹幕功能。通过获取DOM元素、动态创建span标签、随机定位及定时器控制位移,实现弹幕滚动效果。支持点击按钮与键盘回车键发送,适合前端初学者参考学习。
前言
前言
弹幕功能概述
当前许多直播平台或视频网站常采用弹幕功能以增强观众互动体验。本文旨在通过一种适合初学者的方法,记录利用JavaScript实现该效果的具体步骤,欢迎资深开发者提出指导意见。
获取DOM元素
第一步,获取文档中的DOM元素。实现此目的有多种方式,本文示例中采用document.querySelector方法进行元素选取。
封装发送函数
第二步,为了兼容键盘与鼠标两种发送方式,封装了一个名为sendMsg的函数。
创建弹幕容器
首先,需要创建一个容器来接收用户编辑的内容。此处使用span标签,当然也可选用其他标签元素。
var oSpan=document.cerateElement(“span”)
插入弹幕元素
接着,将创建的oSpan元素插入到用于展示的oVideoBox容器中。
oVideoBox.appendChild(oSpan)
添加样式类
为oSpan添加class属性,以便通过CSS编辑插入内容的样式,此处也可使用JS动态设置。示例中使用了CSS样式:oSpan.classList.add(“danmu”)。
设置弹幕内容
利用innerHTML拼接用户图像及弹幕内容,此处使用了ES6的模板字符串语法。
oSpan.innerHTML =` < img src ="./source/lei.jpg" /> ${oContent.value}
计算初始位置
计算弹幕出现的初始位置。left位移的初始值设为oVideoBox的宽度,即oVideoBox.offsetWidth,这也是oSpan的初始定位值oSpan.offsetLeft。top位移的初始值设为oVideoBox内部随机生成的高度,以避免弹幕超出显示范围。
var maxTop=oVideoBox…clientHeight-oSpan.offsetHeight;
var top=Math.round(Math.random()*maxTop)
oSpan.style.top = top+ ‘px'
启动动画计时器
JavaScript动画的实现离不开计时器。此处使用setInterval()方法。
var timer=setInterval(()=>{
var left=oSpan.offsetLeft
left-=10
oSpan.style.left= left+ ‘px'
处理边界移除
判断弹幕是否已超出屏幕边界。若超出,则移除对应的计时器及弹幕元素。
if(left<-oSpan.offsetWidtb){
clearInterval(timer);
oSpan.remove();}},100)
函数封装完成
至此,简易版弹幕函数的封装已完成,后续可直接调用该函数。
绑定点击事件
事件触发从点击开始,通过为oSend绑定点击事件oSend.onclick来调用上述函数。
oSend.οnclick=function(){引用函数sendMsg()}
添加键盘事件
此外,可添加键盘Enter键发送功能,采用事件委托方式:window.οnkeydοwn=function(e){...}。
var ev = e || event;
var keyCode = ev.keyCode || ev.which;
按键逻辑判断
判断逻辑中,检查按键的keycode码是否为13(Enter键)以及是否组合了Alt键。
if (keyCode === 13 && ev.altKey) {
sendMsg();}}
HTML结构示例
以下是HTML代码部分,可供练习参考。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>作业_弹幕</title>
<style>
* {
padding: 0;
margin: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.wrapBox {
width: 800px;
height: 550px;
border: 1px solid #000;
margin: 50px auto 0;
}
.videoBox {
height: 500px;
position: relative;
overflow: hidden;
}
.videoBox img {
width: 100%;
height: 100%;
}
video {
width: 100%;
/* height: 500px; */
}
.danmuSend {
display: flex;
height: 50px;
}
#content {
flex: 1;
}
#send {
width: 100px;
}
.danmu {
color: #f00;
font-size: 20px;
position: absolute;
left: 800px;
top: 0;
white-space: nowrap;
}
.danmu img {
width: 60px;
height: 60px;
border-radius: 50%;
vertical-align: middle;
display: inline-block;
}
</style>
</head>
<body>
<div class="wrapBox">
<div class="videoBox">
<img src="../../source/bg.jpg" />
<!-- <span class="danmu">我是弹幕</span> -->
<!-- <span class="danmu">我是弹幕</span>
<span class="danmu">我是弹幕</span>
<span class="danmu">我是弹幕</span>
<span class="danmu">我是弹幕</span> -->
</div>
<div class="danmuSend">
<input id="content" type="text">
<button id="send">发送</button>
</div>
</div>
</body>
JavaScript代码实现
以下是完整的JS代码实现。
<script>
var oSend = document.querySelector('#send');
var oContent = document.querySelector('#content');
var oVideoBox = document.querySelector('.videoBox');
function sendMsg() {
var content = oContent.value;
var oSpan = document.createElement('span');
oSpan.className = 'danmu';
oSpan.innerHTML = `<img src="../../source/bg.jpg">${content}`;
oVideoBox.appendChild(oSpan);
var maxTop = oVideoBox.clientHeight - oSpan.offsetHeight;
oSpan.style.top = Math.round(Math.random() * maxTop) + 'px';
var timer = setInterval(() => {
var left = oSpan.offsetLeft;
left -= 10;
oSpan.style.left = left + 'px';
if (left < -oSpan.offsetWidth) {
clearInterval(timer);
oSpan.remove();
}
}, 100);
}
oSend.onclick = function () {
sendMsg();
}
window.onkeydown = function (e) {
var ev = e || event;
var keyCode = ev.keyCode || ev.which;
if (keyCode === 13 && ev.altKey) {
sendMsg();
}
}
</script>
总结
总结
文章结语
至此,关于原生JS实现弹幕效果的文章介绍完毕。更多相关原生JS实现内容,请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
JavaScript将图片转换为Base64编码的两种途径
2026-11-05 16:43:05
怎么在 Vue 或 React 项目中正确集成 animate.js
2026-11-05 10:23:38
JS注册事件:addEventListener基础语法与参数详解
2026-11-05 08:44:56
JSP和JS的区别:运行环境与服务端/客户端职责解析
2026-11-04 23:34:36
pdf.js 官方下载地址:GitHub Release 获取预编译包
2026-11-04 23:07:27
