前言
除了大家经常提到的自定义事件之外,浏览器本身也支持我们自定义事件,我们常说的自定义事件一般用于项目中的一些通知机制。最近正好看到了这部分,就一起看了下自定义事件不同的实现,以及vue数据响应的基本原理。
浏览器自定义事件
定义
除了我们常见的click,touch等事件之外,浏览器支持我们定义和分发自定义事件。
创建也十分简单:
//创建名为test的自定义事件 var event = new Event('test') //如果是需要更多参数可以这样 var event = new CustomEvent('test', { 'detail': elem.dataset.time });大多数现代浏览器对new Event/CustomEvent 的支持还算可以(IE除外),可以看下具体情况:
可以放心大胆的使用,如果非要兼容IE那么有下面的方式
var event = document.createEvent('Event'); //相关参数 event.initEvent('test', true, true);自定义事件的触发和原生事件类似,可以通过冒泡事件触发。
<form> <textarea></textarea> </form>触发如下,这里就偷个懒,直接拿mdn的源码来示例了,毕竟清晰易懂。
const form = document.querySelector('form'); const textarea = document.querySelector('textarea'); //创建新的事件,允许冒泡,支持传递在details中定义的所有数据 const eventAwesome = new CustomEvent('awesome', { bubbles: true, detail: { text: () => textarea.value } }); //form元素监听自定义的awesome事件,打印text事件的输出 // 也就是text的输出内容 form.addEventListener('awesome', e => console.log(e.detail.text())); // // textarea当输入时,触发awesome textarea.addEventListener('input', e => e.target.dispatchEvent(eventAwesome));上面例子很清晰的展示了自定义事件定义、监听、触发的整个过程,和原生事件的流程相比看起来多了个触发的步骤,原因在原生事件的触发已经被封装无需手动处理而已。
应用
各大js类库
各种js库中用到的也比较多,例如zepto中的tap,原理就是监听touch事件,然后去触发自定的tap事件(当然这种成熟的框架做的是比较严谨的)。可以看下部分代码:
//这里做了个event的map,来将原始事件对应为自定义事件以便处理 // 可以只关注下ontouchstart,这里先判断是否移动端,移动端down就对应touchstart,up对应touchend,后面的可以先不关注 eventMap = (__eventMap && ('down' in __eventMap)) ? __eventMap : ('ontouchstart' in document ? { 'down': 'touchstart', 'up': 'touchend', 'move': 'touchmove', 'cancel': 'touchcancel' } : 'onpointerdown' in document ? { 'down': 'pointerdown', 'up': 'pointerup', 'move': 'pointermove', 'cancel': 'pointercancel' } : 'onmspointerdown' in document ? { 'down': 'MSPointerDown', 'up': 'MSPointerUp',
