91 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
class SyntheticEvent {
 | 
						|
  constructor(nativeEvent) {
 | 
						|
    this.nativeEvent = nativeEvent;
 | 
						|
    this.target = nativeEvent.target;
 | 
						|
    this.currentTarget = null;
 | 
						|
    this.defaultPrevented = false;
 | 
						|
    this.propagationStopped = false; // 添加冒泡停止标志
 | 
						|
  }
 | 
						|
 | 
						|
  preventDefault() {
 | 
						|
    this.nativeEvent.preventDefault();
 | 
						|
    this.defaultPrevented = true;
 | 
						|
  }
 | 
						|
 | 
						|
  stopPropagation() {
 | 
						|
    this.propagationStopped = true; // 标记 SyntheticEvent 冒泡停止
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
class EventSystem {
 | 
						|
  constructor(root) {
 | 
						|
    this.root = root;
 | 
						|
    this.handlers = {};
 | 
						|
  }
 | 
						|
 | 
						|
  on(type, selector, handler) {
 | 
						|
    if (!this.handlers[type]) {
 | 
						|
      this.handlers[type] = [];
 | 
						|
      // 绑定到根元素
 | 
						|
      this.root.addEventListener(type, (event) => this.dispatch(event, type));
 | 
						|
    }
 | 
						|
    this.handlers[type].push({ selector, handler });
 | 
						|
  }
 | 
						|
 | 
						|
  dispatch(nativeEvent, type) {
 | 
						|
    const syntheticEvent = new SyntheticEvent(nativeEvent);
 | 
						|
    let target = nativeEvent.target;
 | 
						|
 | 
						|
    // 模拟冒泡过程
 | 
						|
    while (target && target !== this.root) {
 | 
						|
      if (syntheticEvent.propagationStopped) {
 | 
						|
        break; // 如果已停止冒泡,则退出
 | 
						|
      }
 | 
						|
 | 
						|
      this.handlers[type]?.forEach(({ selector, handler }) => {
 | 
						|
        if (target.matches(selector)) {
 | 
						|
          syntheticEvent.currentTarget = target; // 当前目标元素
 | 
						|
          handler(syntheticEvent);
 | 
						|
 | 
						|
          if (syntheticEvent.propagationStopped) {
 | 
						|
            return; // 停止事件的进一步处理
 | 
						|
          }
 | 
						|
        }
 | 
						|
      });
 | 
						|
 | 
						|
      target = target.parentElement; // 向父节点继续冒泡
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// 获取根节点
 | 
						|
const root = document.getElementById('app');
 | 
						|
 | 
						|
// 创建事件系统
 | 
						|
const eventSystem = new EventSystem(root);
 | 
						|
 | 
						|
// 注册事件
 | 
						|
eventSystem.on('click', '.button', (event) => {
 | 
						|
  console.log('Button clicked:', event.currentTarget.innerText);
 | 
						|
  event.preventDefault();
 | 
						|
});
 | 
						|
 | 
						|
eventSystem.on('click', '.link', (event) => {
 | 
						|
  console.log('Link clicked:', event.currentTarget.href);
 | 
						|
  // event.stopPropagation();
 | 
						|
  // event.preventDefault();
 | 
						|
});
 | 
						|
 | 
						|
eventSystem.on('click', '#i2', (event) => {
 | 
						|
  // console.log('i2 clicked:', event.currentTarget.innerText);
 | 
						|
  console.log('i2 clicked:', event.currentTarget);
 | 
						|
  // event.preventDefault();
 | 
						|
});
 | 
						|
 | 
						|
eventSystem.on('click', '#i2-child', (event) => {
 | 
						|
  // console.log('i2-child clicked:', event.currentTarget.innerText);
 | 
						|
  console.log('i2-child clicked:', event.currentTarget);
 | 
						|
  // event.preventDefault();
 | 
						|
  event.stopPropagation();
 | 
						|
});
 |