JS-理解观察者模式-视频直播弹幕效果
-
观察者模式
=>定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
=>一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
=>使用面向对象技术,可以将这种依赖关系弱化。
=>观察者和被观察者是抽象耦合的。 建立一套触发机制。
-
创建观察者
=>能设置自己的状态, 当我需要改变的时候, 要触发这个方法改变状态
export default class TimeManager{ list = new Set(); ids; static _instance; constructor() { } //时间管理者 (观察者) static get instance(){ //为每一个杯被观察者对象 创建一个时间观察对象 if(!TimeManager._instance){ Object.defineProperty(TimeManager,"_instance",{ value:new TimeManager() }) } return TimeManager._instance; } //增加 add(elem) { this.list.add(elem); if(this.list.size > 0 && !this.ids){ this.ids = setInterval(()=>{ this.update() },16); } } //移除 remove(elem) { this.list.delete(elem); if(this.list.size === 0 && this.ids) { clearInterval(this.ids); this.ids = undefined; } } //更新 update(){ this.list.forEach(item=>{ if(item.update) item.update(); }) } }
-
创建被观察者(弹幕)
=>当达到某种状态时,触发观察者对象,进行状态的更新
import TimeManager from "./TimeManager.js"; export default class Bullet{ elem; rect; width; x; speed = 2; constructor(txt) { this.elem = this.createElem(txt); } //创建元素 createElem(txt) { //如果该元素存在则返回该元素 if(this.elem) return this.elem; var div = document.createElement('div'); //设定不换行 定位 Object.assign(div.style,{ whiteSpace: "nowrap", position:"absolute", }) //将文本内容添加到弹幕中 div.innerText = txt; //返回该元素 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,{ left: this.rect.width + "px", //每一条弹幕的top随机值 设置为视频高度的三分之一 top:Math.random() * this.rect.height / 4 + 'px', }) //定义全局变量 this.x = this.rect.width; //获取弹幕的宽度 this.width = this.elem.offsetWidth; //给每一条弹幕添加时间观察者 TimeManager.instance.add(this); } //更新元素的状态 update() { if(!this.width) return; //让弹幕在滚动 this.x-=this.speed; this.elem.style.left=this.x+"px"; //当满足弹幕完全移出视频时 if(this.x<-this.width){ //移除该时间观察者 TimeManager.instance.remove(this); //移除该元素 this.elem.remove(); //将该元素置空 this.elem=null; } } }
-
通俗理解观察者模式
=>拍卖会的拍卖者 (被观察者)
=>竞拍者(观察者)
=>拍卖,起拍价格开始
=>当拍卖者宣布第一次价格后,竞拍者开始拍出自己的价格,而拍卖者也会随之改变起拍价格,即为每一次的被观察者状态,这个状态会持续改变,而这个状态的改变是因为竞拍者的价格一次次提高。
=>所以我们需要建立一套触发机制,当被观察者的状态改变时,触发观察者机制。
以上均为个人理解,仅供参考。