Skip to content

自定义事件 #26

Open
Open
@TieMuZhen

Description

@TieMuZhen

转载自:YvetteLau/Blog#28

自定义 DOM 事件(不考虑IE9之前版本)

自定义事件有三种方法,一种是使用new Event(), 另一种是createEvent('CustomEvent'), 另一种是new customEvent()

1、使用new Event()
获取不到event.detail

let btn = document.querySelector('#btn');
let ev = new Event('alert', {
    bubbles: true,    //事件是否冒泡;默认值false
    cancelable: true, //事件能否被取消;默认值false
    composed: false
});
btn.addEventListener('alert', function (event) {
    console.log(event.bubbles); //true
    console.log(event.cancelable); //true
    console.log(event.detail); //undefined
}, false);
btn.dispatchEvent(ev);

2、使用createEvent('CustomEvent')(DOM3)
要创建自定义事件,可以调用createEvent('CustomEvent'),返回的对象有 initCustomEvent 方法,接受以下四个参数:

  • type: 字符串,表示触发的事件类型,如此处的'alert'
  • bubbles: 布尔值: 表示事件是否冒泡
  • cancelable: 布尔值,表示事件是否可以取消
  • detail: 任意值,保存在 event 对象的 detail 属性中
let btn = document.querySelector('#btn');
let ev = btn.createEvent('CustomEvent');
ev.initCustomEvent('alert', true, true, 'button');
btn.addEventListener('alert', function (event) {
    console.log(event.bubbles); //true
    console.log(event.cancelable);//true
    console.log(event.detail); //button
}, false);
btn.dispatchEvent(ev);

3、使用new customEvent()(DOM4)
使用起来比createEvent('CustomEvent')更加方便

var btn = document.querySelector('#btn');
/*
 * 第一个参数是事件类型
 * 第二个参数是一个对象
 */
var ev = new CustomEvent('alert', {
    bubbles: 'true',
    cancelable: 'true',
    detail: 'button'
});
btn.addEventListener('alert', function (event) {
    console.log(event.bubbles); //true
    console.log(event.cancelable);//true
    console.log(event.detail); //button
}, false);
btn.dispatchEvent(ev);

自定义非 DOM 事件(观察者模式)

EventTarget类型有一个单独的属性handlers,用于存储事件处理程序(观察者)。

addHandler() 用于注册给定类型事件的事件处理程序;

fire() 用于触发一个事件;

removeHandler() 用于注销某个事件类型的事件处理程序。

function EventTarget(){
    this.handlers = {};
}

EventTarget.prototype = {
    constructor:EventTarget,
    addHandler:function(type,handler){
        if(typeof this.handlers[type] === "undefined"){
            this.handlers[type] = [];
        }
        this.handlers[type].push(handler);
    },
    fire:function(event){
        if(!event.target){
            event.target = this;
        }
        if(this.handlers[event.type] instanceof Array){
            const handlers = this.handlers[event.type];
            handlers.forEach((handler)=>{
                handler(event);
            });
        }
    },
    removeHandler:function(type,handler){
        if(this.handlers[type] instanceof Array){
            const handlers = this.handlers[type];
            for(var i = 0,len = handlers.length; i < len; i++){
                if(handlers[i] === handler){
                    break;
                }
            }
            handlers.splice(i,1);
        }
    }
}
//使用
function handleMessage(event){
    console.log(event.message);
}
//创建一个新对象
var target = new EventTarget();
//添加一个事件处理程序
target.addHandler("message", handleMessage);
//触发事件
target.fire({type:"message", message:"Hi"}); //Hi
//删除事件处理程序
target.removeHandler("message",handleMessage);
//再次触发事件,没有事件处理程序
target.fire({type:"message",message: "Hi"});

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions