Your UI needs some way to let the user defocus from some selected element, maybe hiding the transformer or closing a popup. How to do that easily?
Sure, this can be done by checking the Node.ClassName of whatever got clicked in the stage listener. A Konva className is the name of the node-type, for example 'Stage', 'Layer', or 'Rect', etc.
You did know that in Konva the click events bubble up the node hierarchy? In case you're not aware of the node structure, see this blog post for an explanation of that an more about some effects.
That looks like this:
stage.on('click' (e) => {
if (e.target && e.target.getClassName() === 'some class name"
// do something fun....
}
}So we could watch out for the value from getClassName() being 'Stage', or 'Layer' and assume that's the user wanting to defocus that popup or transformer.
But a neater option is to use the node.name attribute. I explained the use of node.name in this post about a Konva solution for selection by CSS class names. You did know CSS selectors don't work inside HTML5 canvas - if not read this catchup for experienced devs coming to canvas from DOM for useful information about this and other differences between these worlds.
I promised a neater approach. Here I use Node.addName to attach the name 'background' to the stage, layer, and a shape called grid (imagine a grid drawn on the stage). Now the logic of our test can use the assigned name and not worry about Konva class names.
stage.addName('background')
layer.addName('background')
grid.addName('background')
stage.on('click', (e) => {
const target = e.target;
if (!target || target.hasName('background')) {
// do something fun....
}
});At first viewing there's not mush difference between the two approaches shown. However, think about the case where you have a Konva.Rect or Konva.Image as a large background item. In the first code example, using 'Konva.Rect' as a comparison value would likely become problematic because we often have more than a few Rect's in our Konva constructions!
Note #1: we need to remember that this all operates by event bubbling. The one consideration to keep in mind is that if we cancel bubbling then the stage will not receive the click!
Note #2 - when setting names be aware that using plain Node.name('theName") will replace any current names assigned to the node. If that's what you intend then go ahead, otherwise use Konva.addName('theName') to add the given name into the list of names assigned to the node, leaving whatever pre-existing names in place.
Summary
We've seen a couple of ways to detect a defocusing click, one using class names and a neater approach using name assignment. Name assignment is a useful technique for a number of similar cases where we need to recognise a specific shape or one of a number of somehow related shapes.
Thanks for reading.
VW. Mar 2025