LV1 · 0 XPLog in
Learning path

Lesson 5 of 5 · Client-Side Logic

DOM Events

Connect a page control to JavaScript so a click produces a visible response.

This lesson is locked. You can read ahead, but finish earlier stops to earn progress.

Listen

Watch

Video coming soon

Read

Find the element you need

The DOM (Document Object Model) is the browser’s live representation of your HTML. JavaScript can find an element in that tree, then read or change it. Use document.querySelector('.card') for any CSS selector: a class, tag, attribute or ID. It returns the first match, or null if nothing matches. For an ID, document.getElementById('total') is a direct, readable option; do not include the hash. In your button quest, select the button and the place where its result should appear.

MethodExampleFinds
querySelector'.card'First CSS-selector match
getElementById'total'Element with that ID

Listen before reacting

A click is an event: a signal from the browser that something happened. Attach a listener with addEventListener('click', fn). The function runs when the user clicks, rather than immediately when the page loads. The reliable order is select → listen → react: find the element, register what event matters, then put the response inside the handler. This is exactly the sequence you will use to wire a button.

js
const button = document.querySelector('.card-button');
const output = document.getElementById('total');
button.addEventListener('click', () => {
  output.textContent = 'Ready';
});

The example updates a label; your activity can use its own message or calculation. If you attach a listener before selecting the element, or select a selector that matches nothing, the interaction will fail.

Read inputs and show results

For an input such as <input id="name">, read document.getElementById('name').value. Input values are strings, even when the field looks numeric, so convert them with Number(value) before doing arithmetic. To display plain text, set el.textContent. It replaces the element’s text safely and makes the result visible without interpreting it as HTML.

When building your interactive XP calculator, read the chosen values inside the click handler, calculate from your data, then update the result element’s textContent. That keeps the page responsive to the user’s current choices.

Debug the interaction

If clicking seems to do nothing, open the browser’s developer tools and check the Console. Errors often name the file and line where JavaScript stopped; a null-element error commonly means the selector did not match. Confirm the element exists, the script runs after the HTML is available, and the handler is registered on the intended button.

This troubleshooting habit matters because a visible symptom can hide a small selection or timing mistake. Test one click after each change, and use the console’s error details to guide your next check.

Rehearse a state change, not just a fixed message

Put a button and an output in your own local practice HTML and link app.js with defer:

html
<button id="practice-count">Add one</button>
<p id="practice-total" aria-live="polite">0</p>
js
const countButton = document.getElementById('practice-count');
const countOutput = document.getElementById('practice-total');
let clicks = 0;
function countClick() {
  if (!countOutput) return;
  clicks = clicks + 1;
  countOutput.textContent = String(clicks);
}
countButton?.addEventListener('click', countClick);

Initial state is 0; after one click it is 1; after another it is 2. The value lives outside the handler so it persists between calls. Setting clicks to 0 inside the function would reset it on every click. Passing countClick registers the function; passing countClick() calls it immediately instead.

Buttons already support keyboard activation. Use Tab to focus and Enter/Space to activate; do not replace a button with a clickable div. If a button is inside a form but should not submit it, give it type="button". For a real form submission, use its submit event and prevent default navigation only when your JavaScript handles the submit.

From one input to every calculator row

The input event fires as the value changes; change commonly waits for a committed change. Use input for your live total. querySelector returns one match, while querySelectorAll returns a collection you can iterate. Attach a listener to each rendered quantity input after the rows exist; selecting inputs before rendering yields no useful collection.

Each quantity needs a label with a matching unique id. On an input event, read all current quantities, convert/validate them, recalculate from zero and update the total. Test first row, last row, zero and blank. If only the first row affects the result, inspect your selection and listener registration.

Keep the original fixed-message practice and this stateful counter distinct: both are valid interactions, but the counter teaches repeated state changes. In your assessment use your own data and controls. Verify a click by observing the page and Console, and verify several input changes without reloading.

Key terms

DOM
The browser’s tree-like representation of the page.
selector
A CSS pattern used to locate matching page elements.
event listener
A function registered to respond to an event.
textContent
A property for reading or replacing an element’s plain text.

Summary — copy into your notes

  • Find elements with querySelector or getElementById.
  • Use the select → listen → react order for a click.
  • Read input values and show results with textContent.
  • Check the Console when an interaction fails.