Reading Element State
Once you have $0, you can read and manipulate an element's state. These three properties are your primary tools: classList, dataset, and style.
The Three State Properties
Every DOM element has these properties. They're how JavaScript (and you, in the Console) read and change what an element looks like and how it behaves.
| Property | What It Controls | Example |
|---|---|---|
classList |
CSS classes on the element | $0.classList.add('active') |
dataset |
Data attributes (data-*) |
$0.dataset.state = 'open' |
style |
Inline styles | $0.style.color = 'red' |
classList
The classList property gives you a live list of all classes on an element, plus methods to modify them.
Reading classes
// See all classes
$0.classList
→ DOMTokenList ["card", "featured", "active"]
// Check if a class exists
$0.classList.contains('active')
→ true
// Get the class string (like the HTML attribute)
$0.className
→ "card featured active"
Modifying classes
// Add a class
$0.classList.add('highlighted')
// Remove a class
$0.classList.remove('hidden')
// Toggle: add if missing, remove if present
$0.classList.toggle('active')
// Replace one class with another
$0.classList.replace('old-class', 'new-class')
Most interactive behavior in modern web design works by toggling classes. A button becomes "active", a menu becomes "open", a card becomes "selected". Understanding classList is understanding how interactions work.
Your theme toggle in Week 1 will use classList.toggle() or dataset.theme to switch between light and dark modes. Practice these commands now—you'll use them constantly.
dataset
The dataset property gives you access to all data-* attributes on an element. These are custom attributes you can use to store information.
HTML example
<!-- HTML -->
<button data-action="submit" data-loading="false">
Submit
</button>
Reading data attributes
// See all data attributes as an object
$0.dataset
→ DOMStringMap { action: "submit", loading: "false" }
// Read a specific attribute
$0.dataset.action
→ "submit"
// Note: data-loading becomes dataset.loading (camelCase)
$0.dataset.loading
→ "false"
Modifying data attributes
// Change a value
$0.dataset.loading = 'true'
// Add a new data attribute
$0.dataset.submitted = 'yes'
// Creates: data-submitted="yes"
// Remove a data attribute
delete $0.dataset.loading
You can style based on data attributes using CSS attribute selectors: [data-loading="true"] { opacity: 0.5; }. This is a powerful pattern for state-driven styling.
style
The style property controls inline styles—styles applied directly to the element via the style attribute.
// Read an inline style
$0.style.backgroundColor
→ "coral" // or "" if not set inline
// Set an inline style
$0.style.backgroundColor = '#01B799'
$0.style.padding = '20px'
$0.style.transform = 'scale(1.1)'
// Remove an inline style
$0.style.backgroundColor = ''
$0.style only shows inline styles. To see the final computed value (after all CSS rules), use getComputedStyle($0).propertyName.
Watching Events
DevTools can show you which events fire on an element. This is incredibly useful for understanding interaction behavior.
monitorEvents()
This Console-only function logs all events that fire on an element:
// Watch ALL events on the selected element
monitorEvents($0)
// Watch specific event types
monitorEvents($0, 'click')
monitorEvents($0, ['click', 'focus', 'blur'])
// Stop watching
unmonitorEvents($0)
Event categories
You can also monitor categories of events:
'mouse'— click, mousedown, mouseup, mousemove, etc.'key'— keydown, keyup, keypress'touch'— touchstart, touchmove, touchend'focus'— focus, blur, focusin, focusout
- Select any button on a page
- Run
monitorEvents($0, ['click', 'focus', 'blur']) - Click the button, tab to it, tab away
- Watch the Console log each event
- Run
unmonitorEvents($0)when done
Making Elements Talk
Strategic console.log() placement is how you make your code explain itself. Here are patterns that help designers understand behavior.
Log objects, not just strings
// Less useful
console.log('Button classes: ' + button.className)
// More useful — logs the actual object you can expand
console.log('Button:', button)
console.log('Classes:', button.classList)
Log at key moments
button.addEventListener('click', () => {
console.log('Before toggle:', button.classList.contains('active'))
button.classList.toggle('active')
console.log('After toggle:', button.classList.contains('active'))
})
Group related logs
console.group('Theme Switch')
console.log('Current theme:', document.body.dataset.theme)
console.log('Switching to:', newTheme)
console.groupEnd()
console.log() is your debugging superpower. When something doesn't work, add logs before and after the action. The difference between "before" and "after" tells you what changed (or didn't).