實現一個自定義event事件,包括on ,off,trigger,once


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);

或者可以使用上一章節的內容進行測試https://www.cnblogs.com/yinping/p/10697083.html

在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);
            }
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM