欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

实现一个自定义event事件,包括on ,off,trigger,once

程序员文章站 2022-04-09 17:42:04
on监听事件,off取消事件 ,trigger触发事件,once只执行一次 测试脚本 或者可以使用上一章节的内容进行测试https://www.cnblogs.com/yinping/p/10697083.html 在function函数添加监听函数 同时在move,start中添加触发函数 ......

on监听事件,off取消事件 ,trigger触发事件,once只执行一次

class event {
    constructor() {
        this.handlers = {};//记录所有的事件以及处理函数
        /*
            {
                click:[fn1,fn2],
                mouseover: [fn3,fn4]
            }
        */
    }
    /**
     * on 添加事件监听
     * @param {事件类型} type 
     * @param {事件处理函数} handler 
     */
    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  取消事件监听
     * @param {要取消的事件类型} type 
     * @param {要取消的事件函数,如果不传则清除所有} handler 
     */
    off(type, handler) {
        if (this.handlers[type]) {
            if (handler === undefined) {
                this.handlers[type] = [];
            } else {
                this.handlers[type] = this.handlers[type].filter(f => f != handler);
            }
        }
    }

    /**
     * trigger 执行函数
     * @param {要执行哪个类型的函数} type 
     * @param {事件对象} eventdata 
     * @param {this执行} point 
     */
    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 {要执行的函数} handler 
     */
    once(type, handler) {
        this.on(type, handler, true);
    }
}

测试脚本

let e = new event;
        e.on("click", () => {
            console.log(1);

        })
        e.on("click", () => {
            console.log(2);

        })
        function fn3() {
            console.log(3);

        }
        e.on("click", fn3);
        console.log(e);

或者可以使用上一章节的内容进行测试

在function函数添加监听函数

(function () {
            let box = document.queryselector("#box");
            let dragbox = new drag(box);
            dragbox.on("dragstart", function (e) { //这里不可以使用箭头函数,否则trigger的call方法无效
                console.log(e, this);

                console.log("开始拖拽");

                this.style.background = "yellow";
            })
            dragbox.on("dragend", function (e) {
                console.log(e, this);

                this.style.background = "red";
            })
            dragbox.once("drag", function () {
                console.log("drag");
            })
        })()

同时在move,start中添加触发函数

class drag extends event {
            //构造函数
            constructor(el) {
                super();
                this.el = el;
                //鼠标摁下时的元素位置
                this.startoffset = {};
                //鼠标摁下时的鼠标位置
                this.startpoint = {};
                let move = (e) => {
                    this.move(e);
                };
                let end = (e) => {
                    document.removeeventlistener("mousemove", move);
                    document.removeeventlistener("mouseup", end);
                    this.trigger("dragend", e, this.el);
                };
                el.addeventlistener("mousedown", (e) => {
                    this.start(e);
                    document.addeventlistener("mousemove", move);
                    document.addeventlistener("mouseup", end);
                })
            }
            //摁下时的处理函数
            start(e) {
                let { el } = this;
                this.startoffset = {
                    x: el.offsetleft,
                    y: el.offsettop
                }
                this.startpoint = {
                    x: e.clientx,
                    y: e.clienty
                }
                this.trigger("dragstart", e, el);

            }
            //鼠标移动时的处理函数
            move(e) {
                let { el, startoffset, startpoint } = this;
                let newpoint = {
                    x: e.clientx,
                    y: e.clienty
                }
                let dis = {
                    x: newpoint.x - startpoint.x,
                    y: newpoint.y - startpoint.y,
                }
                el.style.left = dis.x + startoffset.x + "px";
                el.style.top = dis.y + startoffset.y + "px";
                this.trigger('drag', e, el);
            }
        }