视频弹幕
介绍
弹幕指直接显现在视频上的评论,可以以滚动、停留甚至更多动作特效方式出现在视频上,是观看视频的人发送的简短评论。通过发送弹幕可以给观众一种“实时互动”的错觉,弹幕的出现让观看过程充满乐趣。本题需要在已提供的基础项目中,完成视频弹幕的功能。
准备
开始答题前,需要先打开本题的项目代码文件夹,目录结构如下:
1 2 3 4 5 6 7 8
| ├── effect.gif ├── css │ └── index.css ├── video │ └── video1.webm ├── index.html └── js └── index.js
|
其中:
index.html 是主页面。
js/index.js 是需要补充代码的 js 文件。
css/index.css 是样式文件。
effect.gif 是完成的效果图。
video 是存放视频的文件夹。
注意:打开环境后发现缺少项目代码,请手动输入下述命令进行下载:
1 2 3
| cd /home/project wget -q https://labfile.oss.aliyuncs.com/courses/18213/test6.zip unzip test6.zip && rm test6.zip
|
在浏览器中预览 index.html 页面,显示如下所示:

目标
请在 js/index.js 文件中补全代码。具体需求如下:
- 补全
renderBullet 函数中的代码,控制弹幕的显示颜色和移动。功能说明如下:
元素节点相对于
元素绝对定位 ,初始位置的
是
元素的宽,
是
元素的高内的随机数。
注意:需求中所需样式可直接通过已提供的 getEleStyle 方法获取。
- 补全
#sendBulletBtn 元素的绑定事件,点击发送按钮,输入框中的文字出现在弹幕中,样式不同于普通弹幕(样式红色字体红色框已设置,类名为 create-bullet )。通过调用 renderBullet 方法和正确的传参实现功能。
最终效果可参考文件夹下面的 gif 图,图片名称为 effect.gif(提示:可以通过 VS Code 或者浏览器预览 gif 图片)。

规定
- 请勿修改
js/index.js 文件外的任何内容。
- 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径、class 名、id 名、图片名等,以免造成无法判题通过。
判分标准
总通过次数: 663 | 总提交次数: 729 | 通过率: 90.9%
难度: 中等 标签: 蓝桥杯, 2023, 省赛, Web 前端, JavaScript, HTML5
题解
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| const bullets = [ "前方高能", "原来如此", "这么简单", "学到了", "学费了", "666666", "111111", "workerman", "学习了", "别走,奋斗到天明"];
function renderBullet(bulletConfig, videoEle, isCreate = false) { const spanEle = document.createElement("SPAN"); spanEle.classList.add(`bullet${index}`); if (isCreate) { spanEle.classList.add("create-bullet") } spanEle.innerText = bulletConfig.value let {width: videoEleWidth, height: videoEleHeight} = getEleStyle(videoEle) let timer = null
spanEle.style.left = `${videoEleWidth}px` spanEle.style.top = `${getRandomNum(videoEleHeight)}px` videoEle.appendChild(spanEle) let {width: spanEleWidth, left: spanEleLeft} = getEleStyle(spanEle) console.log(spanEleWidth); timer = setInterval(() => { videoEleWidth -= bulletConfig.speed spanEle.style.left = `${videoEleWidth}px` if (videoEleWidth + spanEleWidth <= 0) { console.log(spanEleLeft, videoEleWidth); videoEle.removeChild(spanEle) clearInterval(timer) } }, bulletConfig.time) spanEle.style.color = `RGB(${getRandomNum(255)}, ${getRandomNum(255)}, ${getRandomNum(255)})` }
document.querySelector("#sendBulletBtn").addEventListener('click', () => { const sendInput = document.getElementById('bulletContent') const bulletConfig = { isHide: false, speed: 5, time: 50, value: sendInput.value } const videoEle = document.querySelector("#video"); renderBullet(bulletConfig, videoEle, true) })
function getEleStyle(ele) { return ele.getBoundingClientRect(); }
function getRandomNum(end, start = 0) { return Math.floor(start + Math.random() * (end - start + 1)); }
let index = 0; const videoEle = document.querySelector("#video");
const bulletConfig = { isHide: false, speed: 5, time: 50, value:"" } let isPlay = false; let timer; document.querySelector("#vd").addEventListener('play', () => { isPlay = true; bulletConfig.value = bullets[index++]; renderBullet(bulletConfig, videoEle); timer = setInterval(() => { bulletConfig.value = bullets[index++]; renderBullet(bulletConfig, videoEle); if (index >= bullets.length) { index = 0; } }, 1000); })
document.querySelector("#vd").addEventListener("pause", () => { isPlay = false; clearInterval(timer); })
document.querySelector("#switchButton").addEventListener("change", (e) => { if (e.target.checked) { bulletConfig.isHide = false; } else { bulletConfig.isHide = true; } })
|