头条面试题-创建一个Event类,并创建on、off、trigger、once方法
一、创建一个Event.js
class Event { constructor() { this.handlers = { // 记录所有的事件和处理函数 } } /* * * on 添加事件监听 * @param type 事件类型 * @param handler 事件回调 * on('click', ()=>{}) * */ on(type, handler, once=false) { if (!this.handlers[type]) { this.handlers[type] = []; } if (!this.handlers[type].includes(handler)) { this.handlers[type].push(handler); handler.once = once; } } /* * * off 取消事件监听 * * */ off(type, handler) { if (this.handlers[type]) { if (handler === undefined) { this.handlers[type] = [] } else { this.handlers[type] = this.handlers[type].filter((f)=>{ return f!=handler }) } } } /* * * @param type 要执行哪个类型的函数 * @param eventData事件对象 * @param point this指向 * * */ trigger(type, eventData = {}, point=this) { if (this.handlers[type]) { this.handlers[type].forEach(f => { f.call(point, eventData); if (f.once) { this.off(type, f) } }); } } /* * * once 函数执行一次 * @param type 事件处理 * @param handle 事件处理函数 * */ once(type, handler) { this.on(type, handler, true); } }
二、使用Event.js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> #box { position: absolute; top: 0; left: 0; width: 100px; height: 100px; background: red; } </style> <script src="./event.js"></script> </head> <body> <div id="box"></div> <script> /* * 1.记录摁下时鼠标的位置和元素位置 * 鼠标位置-摁下时的鼠标位置 = 鼠标移动的位置 * 元素位置=鼠标移动距离+摁下时元素位置 **/ class Drag extends Event{ // 构造函数 constructor(el) { super(); // 继承 this.el = el; this.startOffset = null; // 鼠标摁下时元素的位置 this.startPoint = null; // 鼠标的坐标 let move = (e)=>{ this.move(e) } let end = (e)=>{ document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', end); this.end(e) } el.addEventListener('mousedown', (e)=> { this.start(e); document.addEventListener('mousemove', move); document.addEventListener('mouseup', end); }) } start(e) { let {el} = this; console.log(this) console.log(el) this.startOffset = { x: el.offsetLeft, y: el.offsetTop } this.startPoint = { x: e.clientX, y: e.clientY } this.trigger('dragstart', e, this.el) } end(e) { this.trigger('dragend',e, this.el) } move(e) { let {el, startOffset, startPoint} = this; let nowPoint = { x: e.clientX, y: e.clientY } let dis = { x: nowPoint.x - startPoint.x, y: nowPoint.y - startPoint.y } el.style.left = dis.x + startOffset.x + 'px'; el.style.top = dis.y + startOffset.y + 'px'; this.trigger('dragmove', e, el) } } (function() { let box = document.querySelector('#box'); let dragBox = new Drag(box); dragBox.on('dragstart', function(e) { console.log(e); console.log(this); this.style.background = 'yellow'; }) dragBox.on('dragend', function(e) { console.log('b') this.style.background = 'blue'; }) dragBox.once('dragmove', function(e) { console.log('c') // this.style.background = 'blue'; }) console.log(dragBox) })() </script> </body> </html>