什么是观察者模式?
? ? ? ? 观察者模式是一对多的一种依赖关系,让多个观察者对象同时监听某一个主体对象。这个主体发生状态的时候。会通知所有的观察者对象,自动更新自己的状态。
? ? ? ? 而发布订阅者模式,则不同。发布订阅者模式是一种多对多的依赖关系。通过事件的绑定,通知给需要接受的订阅者,让订阅者更新自己的状态。
? ? ? ? 两种之间的区别在于观察者模式知道自己所派发的目标对象是谁。而发布订阅者模式观察者和订阅者之间不清楚对方是谁。是由中间层进行交互完成派发任务。
写一个通过输入对应的字母的案例
<body>
<input>
<p>A</p>
<p>B</p>
<p>C</p>
<p>数字</p>
</body>
通过input框中输入的值。通过addEventListener来监听每次输入的值来是否让对应的字母进行高亮显示。
<script>
let inp = document.querySelector('input')
var A = document.querySelector('#A');
var B = document.querySelector('#B')
var C = document.querySelector('#C')
var num = document.querySelector('#num')
inp.addEventListener('input', function () {
A.classList.toggle('active', this.value.indexOf('A') !== -1)
B.classList.toggle('active', this.value.indexOf('B') !== -1)
C.classList.toggle('active', this.value.indexOf('C') !== -1)
num.classList.toggle('active', /\d/.test(this.value))
})
</script>
那么接下来通过面向对象的方式,将这块重新编写一边。
<script>
class inp {
// 在构造函数里面编写属性
constructor(el) {
this.observers = [];
// 通过监听input框的变化将变化的值传给所有的观察者
el.addEventListener('input', (e) => {
this.allNotify(e.target.value)
})
}
allNotify(value) {
this.observers.forEach(item => {
item.notify(value)
})
}
addObserver(ob) {
this.observers.push(ob)
}
}
// DocumentFragment对象 一般动态创建html元素都需要创建好添加到html会导致页面回流,
// DocumentFragment对象是通过一次性将子孙节点添加进。因此性能会有效的提高
class observer extends DocumentFragment {
constructor(txt) {
super()
// 在每次new一个的时候创建对应的节点
this.p = document.createElement('p');
this.p.innerHTML = txt
document.querySelector('body').append(this.p)
}
// 通过匹配到对应的字符出现对应的方法
notify(value) {
this.p.classList.toggle('active', this.handle(value))
console.log(this.handle(value));
}
}
class alphabet extends observer {
constructor(txt) {
super(txt)
this.txt = txt
}
handle(value) {
// 当每次变化的值indexOf不为-1说明有相对应的值
return value.indexOf(this.txt) !== -1
}
}
class num extends observer {
constructor(txt) {
super(txt)
this.txt = txt
}
handle(value) {
// 通过正则来判断是否有数字
return /\d/.test(this.txt)
}
}
const inpK = new inp(document.querySelector('input'));
inpK.addObserver(new alphabet('A'))
inpK.addObserver(new alphabet('B'))
inpK.addObserver(new alphabet('C'))
inpK.addObserver(new num('数字'))
</script>
|