console
const { log, dir, table, clear, warn, error } = console; clear();
const input = document.querySelector('input')
const textarea = document.querySelector('textarea')
const text1 = document.querySelector('.text1')
const text2 = document.querySelector('.text2')
const btn1 = document.querySelector('.btn1')
const btn2 = document.querySelector('.btn2')
class Signal {
constructor(initialValue) {
this.value = initialValue;
this.subscribers = new Map();
this.nextId = 0;
}
get() {
return this.value;
}
set(newValue) {
if (this.value !== newValue) {
this.value = newValue;
this.subscribers.forEach((callback) => callback(newValue));
}
}
subscribe(callback) {
const id = this.nextId++;
this.subscribers.set(id, callback);
return id;
}
unsubscribe(id) {
this.subscribers.delete(id);
}
}
const signal = new Signal('hello world')
let subId1 = signal.subscribe(update1)
let subId2 = signal.subscribe(update2)
signal.set('hello')
input.onkeyup = () => signal.set(input.value)
textarea.onkeyup = () => signal.set(textarea.value)
btn1.addEventListener('click', () => { signal.unsubscribe(subId1) })
btn2.addEventListener('click', () => { subId1 = signal.subscribe(update1) })
function update1(value) {
input.value = value
textarea.value = value
text1.innerText = value
}
function update2(value) {
text2.innerText = value
}
const text3 = document.querySelector('.text3')
const sg2 = new Signal('hi there!')
let count = 0
sg2.subscribe(val=>text3.innerText=val)
setInterval(()=>{
sg2.set(++count)
}, 500)
<div class="container">
<p class="text1"></p>
<input id="elm1" type="text">
<textarea id="elm2" name="" cols="" rows=""></textarea>
<p class="text2" style="color:red">...</p>
<button class="btn1">取消第一个订阅(第二个订阅仍会同步)</button>
<button class="btn2">重新订阅</button>
<hr>
<p class="text3"></p>
</div>
:root {
--tiny-width: 70%;
}
html, body {
height: 100%;
margin: 0;
padding: 10px;
background: #f2f5f7;
}
.hide {
visibility: hidden;
pointer-events: none;
right: calc(-1 * var(--tiny-width)) !important;
}
.CodeMirror {
flex: 1;
}
.popup {
display: flex;
flex-direction: column;
position: absolute;
width: var(--tiny-width);
min-width: 300px;
height: 100%;
top: 0;
right: 0px;
padding: 20px;
z-index: 99999;
background: #ffffffdd;
backdrop-filter: blur(5px);
transition: .3s;
box-shadow: 0 0 8px #00000033;
}