头条面试题-创建一个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>

 

posted @ 2019-05-24 15:42  史海莹  阅读(912)  评论(0编辑  收藏  举报