<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<input type="text" class="js-input" placeholder="type something here" style="margin-bottom:20px;" />
<div>
<button class="js-subscribe-p1">Subscribe</button>
<button class="js-unsubscribe-p1">Unsubscribe</button>
<div>
P1:<span class="js-p1"></span>
</div>
</div>
<div>
<button class="js-subscribe-p2">Subscribe</button>
<button class="js-unsubscribe-p2">Unsubscribe</button>
<div>
P2:<span class="js-p2"></span>
</div>
</div>
<div>
<button class="js-subscribe-p3">Subscribe</button>
<button class="js-unsubscribe-p3">Unsubscribe</button>
<div>
P3:<span class="js-p3"></span>
</div>
</div>
<script>
class Observable {
constructor() {
this.observers = [];
}
subscribe(f) {
this.observers.push(f);
}
unsubscribe(f) {
this.observers = this.observers.filter(subscriber => subscriber !== f);
}
notify(data) {
this.observers.forEach(observer => observer(data));
}
}
const input = document.querySelector('.js-input');
const ps = document.querySelectorAll('span[class*=js-p]');
const subscribePs = document.querySelectorAll('[class*=js-subscribe-p]');
const unsubscribePs = document.querySelectorAll('[class*=js-unsubscribe-p]');
const updateP1 = text => ps[0].textContent = text;
const updateP2 = text => ps[1].textContent = text;
const updateP3 = text => ps[2].textContent = text;
const headingsObserver = new Observable();
headingsObserver.subscribe(updateP1);
headingsObserver.subscribe(updateP2);
headingsObserver.subscribe(updateP3);
subscribePs[0].addEventListener('click', () => headingsObserver.subscribe(updateP1));
unsubscribePs[0].addEventListener('click', () => headingsObserver.unsubscribe(updateP1));
subscribePs[1].addEventListener('click', () => headingsObserver.subscribe(updateP2));
unsubscribePs[1].addEventListener('click', () => headingsObserver.unsubscribe(updateP2));
subscribePs[2].addEventListener('click', () => headingsObserver.subscribe(updateP3));
unsubscribePs[2].addEventListener('click', () => headingsObserver.unsubscribe(updateP3));
input.addEventListener('keyup', e => {
headingsObserver.notify(e.target.value);
});
</script>
</body>
</html>