思路:
1、設定video
2、設定輸入框
3、擷取輸入框的内容,添加、删除和更新
4、裡面運用了單廠模式,每次生成的例子都是一樣的。
<!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>
#videobox{
width: 640px;
height: 410px;
overflow: hidden;
margin: 0 auto;
position: relative;
}
input{
width: 630px;
height: 40px;
font-size: 20px;
border: 2px solid #8b8a8a;
}
</style>
</head>
<body>
<div id="videobox">
<video src="./huawuyu.mp4" controls></video>
<input type="text" placeholder="發個友善的彈幕見證當下吧~">
</div>
<script type="module">
// 引入彈幕js檔案
import Bullet from "./js/Bullet.js"
// 擷取輸入框
var input = document.querySelector("input");
// 擷取鍵盤事件
document.addEventListener("keyup",keyHandler);
// 設定鍵盤事件
function keyHandler(e){
// 如果輸入的不是Enter鍵13,跳出
if(e.keyCode !== 13) return;
// 如果是空的,也跳出
if(input.value.trim().length===0) return;
// 建立bullet,裡面的值是輸入框的值
var bullet = new Bullet(input.value);
// 添加到videobox盒子下
bullet.appendTo("#videobox")
// 每次輸入完後,清空輸入框
input.value = "";
}
</script>
</body>
</html>
// 設定Time類
export default class Time{
static _instance;
list = new Set()
isd;
constructor(){
}
// 單例模式 讓每次都是建立相同的例子
static get instance(){
if(!Time._instance){
// 設定屬性
Object.defineProperty(Time,"_instance",{
value:new Time()
})
}
return Time._instance;
}
// 添加
add(elem){
// 把元素放入list
this.list.add(elem);
// 如果清單大于零 且 ids沒有開啟
if(this.list.size>0 && !this.ids)
// 執行updata,16毫秒執行一次
this.ids=setInterval(()=>this.update(),16)
}
// 删除
remove(elem){
// 删除清單的元素
this.list.delete(elem);
// 如果清單長度是零 且 存在ids
if(this.list.size===0 && this.ids){
// 清除定時器
clearInterval(this.ids)
// ids設定為空
this.ids=0;
}
}
// 更新
update(){
// 循環,每次更新
this.list.forEach(item=>{
if(item.update) item.update();
})
}
}
// 引入js檔案
import Time from "./Time.js";
export default class Bullet{
rect;
x;
speed=2
width;
// 初始化,實參等于輸入框的文本
constructor(txt){
// 建立文本元素
this.elem = this.createElem(txt);
}
// 建立文本元素
createElem(txt){
// 如果存在,就用這個元素
if(this.elem) return this.elem;
// 擷取div
var div = document.createElement("div")
// 給div設定樣式
Object.assign(div.style,{
// 白色
color:"#ffffff",
// 字型粗細
fontWeight:"600",
// 不換行
whiteSpace:"nowrap",
// 絕對定位
position:"absolute",
})
// div的文本等于輸入框的文本
div.textContent = txt
// 傳回div
return div
}
// 添加至父容器
appendTo(parent){
// 擷取父容器
if(typeof parent==="string") parent=document.querySelector(parent)
// 給父容器添加子元素
parent.appendChild(this.elem);
// 擷取父容器(矩形)
this.rect = parent.getBoundingClientRect();
// 設定元素的樣式
Object.assign(this.elem.style,{
// 高度是,父容器的四分之一
top:Math.random()*this.rect.height/4+"px",
// 左邊的距離就是父容器的寬度
left:this.rect.width+"px"
})
// 父容器寬度
this.x = this.rect.width;
// 擷取元素的寬度
this.width=this.elem.offsetWidth;
// 添加到類中
Time.instance.add(this)
}
// 更新資料
update(){
// 如果沒有資料跳出
if(!this.width) return;
// 減速設定
this.x -=this.speed
// 減速設定
this.elem.style.left = this.x+"px"
// 當寬度小于父容器寬度時
if(this.x<-this.width){
// 移除例子
Time.instance.remove(this);
// 移除元素
this.elem.remove();
// 給元素設定為null
this.elem = null;
}
}
}