Loading...
Inside the event listener this
should point to the same as e.currentTarget
. However, if the arrow function is used, the context will be lost:
circle.addEventListener('mouseenter', function (e) {console.log(this); // circleconsole.log(e.currentTarget === this); // true});circle.addEventListener('mouseleave', () => {console.log(this); // undefined});
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/mouseenter_event
mouseenter does not bubble, while mouseover does. Similarly mouseleave does not bubble, while mouseout does.
The event system only responds to events within the Canvas canvas. For example, when mousemove is listened to, moving outside of the canvas to other areas of the page does not trigger the event handler. The target property of the event object returns Document when picking up a blank area of the canvas (without hitting any visible graphics).
canvas.addEventListener('mousemove', (e) => {if (e.target.nodeName === 'document') {// move on empty area}});
Some built-in events have an order of firing, for example, the click event will be fired after the pointerdown and pointerup events. In this process, it is possible that the target of the pointerdown and pointerup events may not match. For example, if you press the mouse on one graph, move to another graph and then lift the mouse, we will trigger the click event on an ancestor node that is common to both targets (e.g. the root of the scene graph document.documentElement).
This can be tried in this example.
Sometimes we need to disable the default scrolling behavior of a page, for example when implementing a zoom class. Disabling the default behavior can be done with preventDefault, but the following code will not work in Chrome and the page will still scroll.
canvas.addEventListener('wheel', (e) => {e.preventDefault();});
The reason for this problem is that G added the passive: true
configuration item when listening to the wheel event of the canvas event.
// $el is the DOM element, <canvas> in g-canvas/webgl while <svg> in g-svg$el.addEventListener('wheel', onPointerWheel, {passive: true,capture: true,});
For more information about Passive event handlers, please refer to this article from https://zhuanlan.zhihu.com/p/24555031. The short answer is that this option improves the browser's scrolling smoothness by telling the browser in advance that "I won't block your default scrolling behavior".
Now back to our question, if the user does need to disable the default scrolling behavior, a non-Passive event handler can be manually added to the DOM node of the canvas, g-plugin-control plugin does this. How to get the DOM node of the canvas can be done using getDomElement.
canvas.getContextService().getDomElement() // g-canvas/webgl 为 <canvas>,g-svg 为 <svg>.addEventListener('wheel',(e) => {e.preventDefault();},{ passive: false },);
Most of the other native events, especially keyboard and clipboard events that need to be bound to window/document, have no special usage in G. You can directly refer to the related events documentation.
Sometimes we want to disable the browser's default right-click menu, so we can disable the default behavior in the contextmenu event handler with the preventDefault()
method to disable the default behavior. To get the DOM node of the canvas you can use getDomElement.
canvas.getContextService().getDomElement() // g-canvas/webgl 为 <canvas>,g-svg 为 <svg>.addEventListener('contextmenu', (e) => {e.preventDefault();});
Note that since the default behavior of the rightup / down events is not to pop up the system menu, the following writeup is not valid.
// wrongcanvas.addEventListener('rightup', (e) => {e.preventDefault();});
Use KeyboardEvent directly.
window.addEventListener('keydown', () => {}, false);
However, we have not yet implemented A11y-related features, such as using tabs to toggle selection between shapes within the canvas.
Use ClipboardEvent directly.
We don't have a built-in focus event like focus/blur, so the following code is not valid.
circle.addEventListener('focus', () => {});circle.addEventListener('blur', () => {});
Focus-related functions can be implemented through events such as click/mouseenter/mouseleave. example
Due to the need to be as compatible as possible with PC and mobile events, we do not listen to the native dblclick event, but to the pointerdown property by listening to pointerdown and pointerup, the number of clicks within a certain time interval (200ms) is recorded in the detail attribute, so that it is possible to distinguish between a click and a double click.
canvas.addEventListener('click', (e) => {if (e.detail === 2) {// dbclick} else if (e.detail === 1) {// click}});
The following way of writing delegates in event names is supported in older versions, in the format [delegated-graphic name]:[event-name]
, example.
// Listen for click events bubbling up on all graphs with the name nodegraph.on('node:click', () => {});// orgraph.addEventListener('click', (e) => {if (e.target.name === 'node') {}});
As mentioned before, event binding is not done in the core event system, it should be left to the corresponding rendering environment plugins. For example, g-plugin-dom-interaction which uses DOM API to bind/unbind, other environments such as applets should write their own plugins.
In this class of plugins, we need to complete the binding in init
and the unbinding in destroy
. When implementing the binding, multiple (if any) native events in that rendering environment need to be mapped to G's standard event handlers.
// g-plugin-dom-interactionconst onPointerDown = (ev: InteractivePointerEvent) => {renderingService.hooks.pointerDown.call(ev);};renderingService.hooks.init.tap(DOMInteractionPlugin.tag, () => {// using native DOM API$el.addEventListener('pointerdown', // native eventonPointerDown,true,);// If mobile support is requiredif (supportsTouchEvents) {$el.addEventListener('touchstart', onPointerDown, true);}// ...});renderingService.hooks.destroy.tap(DOMInteractionPlugin.tag, () => {});
Different rendering environments use different pickup plugins for determining the EventTarget of native events.
In g-plugin-a11y, we listen to keyboard events for navigation.