在svelte中下级给上级发射事件一般是这种形式:
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
dispatch("myevent", { });
而 createEventDispatcher 的源码中使用了一个自定义函数custom_event,其源码如下:
function custom_event(type, detail) {
const e = document.createEvent('CustomEvent');
e.initCustomEvent(type, false, false, detail);
return e;
}
由此可以看出,svelte事件的核心知识是CustomEvent,特地找来看了看学习下。
initCustomEvent方法已经Deprecated了
一般的UI Event
平时用的事件都是UI Event, 比如:
- MouseEvent
- TouchEvent
- FocusEvent
- KeyboardEvent
- WheelEvent
- InputEvent
这些事件可以在用户交互的时候触发,也可以在程序中由代码触发,比如:
<button id="elem" onclick="alert('Click!');">Autoclick</button>
<script>
let event = new MouseEvent("click");
elem.dispatchEvent(event);
</script>
上面的代码执行后不需要我们动鼠标点击就会自己弹出来一个alert。
虽然平时不会这么干,但是我们可以使用这种机制来进行组件间的通信啊!独立于框架,可以用在组件或者是普通的DOM节点上。
CustomEvent
event = new CustomEvent(typeArg, customEventInit);
customEventInit是可选参数,对象字面量形式,属性包括:
- detail,类型是any,通过这个传东西
- bubbles,默认false
- cancelable, 默认false
- composed, 默认false
比如下面的用法:
<button id="menu">Menu (click me)</button>
<script>
menu.onclick = function() {
alert(1);
// alert("nested")
menu.dispatchEvent(new CustomEvent("menu-open", {
bubbles: true
}));
alert(2);
};
document.addEventListener('menu-open', () => alert('nested'));
</script>
上面这段的alert顺序是:
1 → nested → 2
之所以是这个结果而不是1 → 2 → nested,是因为在事件的回调函数中dispatch的事件他的回调函数会被同步执行,即便这个dispatch的事件不是自定义的那种也无所谓。
参考文献
- https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
- https://javascript.info/dispatch-events