Back to C++
2026-05-097 min read

JS Event Listener (C++)

Learn JS Event Listener (C++) step by step with clear examples and exercises.

Why This Matters

In modern web development, interactivity is key to creating engaging user experiences. JavaScript event listeners play a crucial role in achieving this by allowing developers to respond to user actions like clicks, keypresses, and more. However, there are scenarios where you might want to use the power of C++ for performance reasons or because you're working on a project that requires a mix of languages. By learning how to implement JavaScript event listeners using C++, you can create more versatile applications that take advantage of both languages.

Prerequisites

To follow this lesson, you should have a basic understanding of:

  1. C++ syntax and programming concepts (variables, functions, classes, etc.)
  2. HTML and JavaScript fundamentals (DOM manipulation, event handling, asynchronous JavaScript, etc.)
  3. How to compile and run C++ code on your system
  4. Familiarity with Emscripten SDK and its usage for compiling C/C++ code to WebAssembly

Core Concept

To create a JavaScript event listener in C++, we will use the Emscripten SDK. Emscripten is a toolchain for compiling C and C++ code to asm.js and WebAssembly, allowing you to write C/C++ code that runs in the browser. It provides a way to create JavaScript APIs from your C++ code, making it possible to use C++ event listeners in JavaScript applications.

Here's an overview of the steps involved:

  1. Install Emscripten: Follow the instructions on the Emscripten website to set up your development environment.
  2. Create a new project: Use emcmake cmake to create a new CMake-based project with Emscripten support.
  3. Write your C++ code: Implement the functionality you want to expose to JavaScript, including any event listeners.
  4. Generate JavaScript API bindings: Run emcc on your C++ source files to generate JavaScript APIs that can be called from JavaScript.
  5. Create an HTML file: Include your generated JavaScript APIs and call them from JavaScript to interact with the C++ code.

Example: Simple Event Listener

Let's create a simple example where we define a C++ function that gets called when a button is clicked in JavaScript.

  1. Create a new Emscripten project:
emcmake cmake -DCMAKE_BUILD_TYPE=Release -DUSE_SDL2=ON -DUSE_EMSCRIPTEN=ON -DEMSCRIPTEN_ENABLE_WASM=ON -DUSE_GLEW=OFF -DUSE_GLFW=OFF -DUSE_OPENMP=OFF -DUSE_X11=OFF -DUSE_SDL2_IMAGE=OFF -DUSE_SDL2_MIXER=OFF -DUSE_SDL2_NET=OFF -DUSE_SDL2_TTF=OFF -DUSE_GLAD=ON -DCMAKE_INSTALL_PREFIX=$HOME/emsdk_v61_apple_clang/upstream/usr
  1. Create a new C++ source file (main.cpp) and implement the event listener:
#include <emscripten/bind.h>
#include <iostream>

EMSCRIPTEN_BINDINGS(my_module) {
function("printMessage", &printMessage);
}

void printMessage() {
std::cout << "Hello from C++!\n";
}
  1. Generate JavaScript API bindings:
emcc main.cpp -o main.js --bind -s EXPORT_NAME=my
  1. Create an HTML file (index.html) that includes the generated JavaScript APIs and calls the event listener:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Event Listener Example</title>
<script src="main.js"></script>
</head>
<body>
<button id="myButton">Click me!</button>
<script>
function handleButtonClick() {
my.printMessage();
}

const button = document.getElementById('myButton');
button.addEventListener('click', handleButtonClick);
</script>
</body>
</html>

Now, when you open the index.html file in a web browser, clicking the "Click me!" button will print "Hello from C++!" to the console.

Worked Example

In this worked example, we'll create an interactive application that updates the text on a canvas element based on user input from the keyboard.

  1. Create a new Emscripten project:
emcmake cmake -DCMAKE_BUILD_TYPE=Release -DUSE_SDL2=ON -DUSE_EMSCRIPTEN=ON -DEMSCRIPTEN_ENABLE_WASM=ON -DUSE_GLEW=OFF -DUSE_GLFW=OFF -DUSE_OPENMP=OFF -DUSE_X11=OFF -DUSE_SDL2_IMAGE=OFF -DUSE_SDL2_MIXER=OFF -DUSE_SDL2_NET=OFF -DUSE_SDL2_TTF=ON -DUSE_GLAD=ON -DCMAKE_INSTALL_PREFIX=$HOME/emsdk_v61_apple_clang/upstream/usr
  1. Create a new C++ source file (main.cpp) and implement the event listener:
#include <emscripten/bind.h>
#include <SDL.h>
#include <iostream>
#include <string>

EMSCRIPTEN_BINDINGS(my_module) {
function("init", &init);
function("update", &update);
}

extern "C" {
void init() {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) {
std::cerr << "Failed to initialize SDL: " << SDL_GetError() << '\n';
exit(1);
}
}

void update(Uint32 time, Uint32 deltaTime) {
// TODO: Implement event handling and canvas updates here
}

std::string getTextFromEvent(SDL_KeyboardEvent* event) {
switch (event->keysym.scancode) {
case SDL_SCANCODE_A: return "Apple";
case SDL_SCANCODE_B: return "Banana";
case SDL_SCANCODE_C: return "Carrot";
// Add more key mappings as needed
default: return "";
}
}

void handleKeyboardEvent(SDL_KeyboardEvent* event) {
if (event->type == SDL_KEYDOWN && event->repeat == 0) {
const std::string text = getTextFromEvent(event);
if (!text.empty()) {
// TODO: Update canvas with new text
}
}
}
}
  1. Generate JavaScript API bindings:
emcc main.cpp -o main.js --bind -s EXPORT_NAME=my
  1. Create an HTML file (index.html) that includes the generated JavaScript APIs and initializes the application:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Event Listener Example</title>
<script src="main.js"></script>
</head>
<body onload="my.init();">
<!-- TODO: Add canvas element and event handling code here -->
<script>
function handleKeydown(event) {
my.handleKeyboardEvent(event);
}

window.addEventListener('keydown', handleKeydown);
</script>
</body>
</html>

Now, you can expand the update() function in your C++ source file to handle keyboard events and update the text on a canvas element based on user input.

Common Mistakes

  1. Forgetting to call emcc with the correct flags: Make sure you're using the correct flags for your project, including setting the export name (-s EXPORT_NAME=my) and enabling WebAssembly support (-DEMSCRIPTEN_ENABLE_WASM=ON).
  2. Failing to initialize SDL correctly: Ensure that you call SDL_Init() in your C++ code before using any SDL functions, and handle errors appropriately.
  3. Not generating JavaScript API bindings: Remember to run emcc on your C++ source files to generate the necessary JavaScript APIs.
  4. Incorrectly defining event handlers: Make sure you understand how to define event listeners in JavaScript and properly connect them to your C++ functions using Emscripten's binding system.
  5. Not handling keyboard events correctly: If you're working on a project that requires input from the user, ensure that you handle keyboard events correctly by checking for relevant key presses and updating your application accordingly.

Practice Questions

  1. How can you create a simple event listener in C++ using Emscripten that prints "Hello from C++!" when a button is clicked?
  2. You have an HTML file with multiple buttons. How would you modify the example provided to print different messages depending on which button was clicked?
  3. Create an interactive application that updates the text on a canvas element based on user input from the keyboard.
  4. How can you create a JavaScript event listener in C++ using Emscripten that responds to a custom event dispatched by JavaScript?
  5. In the worked example, how would you modify the code to update the text on a canvas element instead of printing it to the console?

FAQ

Q: What is Emscripten, and why should I use it for JavaScript event listeners in C++?

A: Emscripten is a toolchain for compiling C and C++ code to asm.js and WebAssembly, allowing you to write C/C++ code that runs in the browser. It provides a way to create JavaScript APIs from your C++ code, making it possible to use C++ event listeners in JavaScript applications.

Q: How do I install Emscripten?

A: Follow the instructions on the Emscripten website to set up your development environment.

Q: What are some common mistakes when implementing JavaScript event listeners using C++ and Emscripten?

A: Common mistakes include forgetting to call emcc with the correct flags, failing to initialize SDL correctly, not generating JavaScript API bindings, incorrectly defining event handlers, and not handling keyboard events correctly.

Q: How can I create a simple event listener in C++ using Emscripten that prints "Hello from C++!" when a button is clicked?

A: Create a new Emscripten project, write a simple C++ function to print the message, generate JavaScript API bindings, and call the function from an HTML file with a button element.

Q: How would I modify the example provided to print different messages depending on which button was clicked?

A: You can pass a parameter to your event listener function in C++ and have JavaScript call the appropriate function based on the button that was clicked.

Q: How can you create a JavaScript event listener in C++ using Emscripten that responds to a custom event dispatched by JavaScript?

A: To create a JavaScript event listener in C++ that responds to a custom event, you'll need to use Emscripten's binding system to define the event and its associated callback in both JavaScript and C++. Then, when the event is dispatched from JavaScript, your C++ code can respond accordingly.

Q: In the worked example, how would you modify the code to update the text on a canvas element instead of printing it to the console?

A: To update the text on a canvas element instead of printing it to the console, you'll need to create a canvas in your HTML file and use SDL2 to draw the text onto that canvas. You can then call the appropriate functions from JavaScript to redraw the canvas whenever the text changes.

JS Event Listener (C++) | C++ | XQA Learn