HTML5 Canvas Remove Event Listener by Name with Konva
Konva event namespaces identify related listeners in imperative code. Add the
namespace after the event type, such as click.menu. Then pass the same name to
off() to remove that listener.
Instructions: Select the circle to run two listeners. Use each button to remove one listener. Then select the circle again.
react-konva does not expose Konva event namespaces through React event props.
React has one prop for each event type, such as onClick. Store enabled states
in React, and conditionally pass one dispatcher to that prop.
- Vanilla
- React
import Konva from 'konva';
const stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
});
const layer = new Konva.Layer();
stage.add(layer);
const circle = new Konva.Circle({
x: stage.width() / 2,
y: stage.height() / 2,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
});
// add click listeners
circle.on('click.event1', function () {
alert('first click listener');
});
circle.on('click.event2', function () {
alert('second click listener');
});
layer.add(circle);
// add buttons to remove listeners
const button1 = document.createElement('button');
button1.innerHTML = 'Remove first listener';
button1.style.position = 'absolute';
button1.style.top = '0';
button1.style.left = '0';
button1.onclick = function() {
circle.off('click.event1');
};
document.getElementById('container').appendChild(button1);
const button2 = document.createElement('button');
button2.innerHTML = 'Remove second listener';
button2.style.position = 'absolute';
button2.style.top = '30px';
button2.style.left = '0';
button2.onclick = function() {
circle.off('click.event2');
};
document.getElementById('container').appendChild(button2);
import { useState } from 'react';
import { Stage, Layer, Circle, Text } from 'react-konva';
const App = () => {
const [firstEnabled, setFirstEnabled] = useState(true);
const [secondEnabled, setSecondEnabled] = useState(true);
const [message, setMessage] = useState('Select the circle');
const handleClick =
firstEnabled || secondEnabled
? () => {
const messages = [];
if (firstEnabled) {
messages.push('first listener');
}
if (secondEnabled) {
messages.push('second listener');
}
setMessage(messages.join(' + '));
}
: undefined;
return (
<>
<button onClick={() => setFirstEnabled(false)}>
Remove first listener
</button>
<button onClick={() => setSecondEnabled(false)}>
Remove second listener
</button>
<Stage width={window.innerWidth} height={360}>
<Layer>
<Text x={20} y={20} text={message} fontSize={18} />
<Circle
x={window.innerWidth / 2}
y={180}
radius={70}
fill="red"
stroke="black"
strokeWidth={4}
onClick={handleClick}
onTap={handleClick}
/>
</Layer>
</Stage>
</>
);
};
export default App;