index.pug for the sort of web project I've been going on about for a while:
html head title Fun With The DOM body h1 Fun With The DOM script(src='js/main.js')
This gets transformed into a web page with the following HTML:
<html> <head> <title>Fun With The DOM</title> </head> <body> <h1>Fun With The DOM</h1> </body> <script src="js/main.js"></script> </html>
When a browser renders that HTML file, it creates an object that models the document, called a document object model or DOM for short. For example, the DOM for this page will have a
body object, and an
h1 object that contains the text "Fun With The DOM"
For example, if I wanted to get the contents of the
h1 element I'd write the following in
Which would display:
Fun With The DOM
to the web console of your choice.
Let's say I had two paragraph elements:
p I like to snuggle with cute goat babies p Goat babies are sooo cute
If I wanted to grab both of them I could do the following:
But what if I only want one of them? I can add an id to one, which will let me grab only the paragraph element with the id I specify:
p I like to snuggle with cute goat babies p(id='cute-goats') Goat babies are sooo cute
Those of you that know a bit of CSS will recognize the
# character as indicating an id.
We can also select by class:
p(class='goat-paragraph') I like to snuggle with cute goat babies p(class='goat-paragraph') Goat babies are sooo cute p(class='robot-paragraph') The robots are after your job!
var R = require('ramda') R.map( R.prop('innerHTML'), document.querySelectorAll('.goat-paragraph')) /*returns [ "I like to snuggle with cute goat babies", "Goat babies are sooo cute" ]*/
# indicates id,
. indicates class.
Let's say we wanted to add a class to a list of elements:
R.map( p => p.classList.add('silly-paragraph'), document.querySelectorAll('.goat-paragraph'))
You can also remove classes with
classList.remove, get a list of any of an element's attributes by simply grabbing its
If you'd like to dynamically modify the contents of a page, here's one way to do it:
document .querySelector('body') .innerHTML = '<p>stuff</p><p>things</p>'
I'd say there are limits to this. I don't think this is the way to build large single-page-applications. Eventually it becomes a better idea to start using a templating library like Mustache.js or web frameworks like Angular or React
In any event, I think learning how to directly manipulate the DOM is useful, even if you plan to use web frameworks most of the time.
What about doing things when a user clicks a button? Here's a way to add that behavior to a web page:
html head title Fun With The Dom body h1(id='message') You haven't clicked it yet button(id='clickit') click it script(src='js/main.js')
document.querySelector('#clickit').onclick = () => document.querySelector('#message').innerHTML = 'You clicked it!'
I recommend checking out the Mozilla Developer Network's page about DOM elements as well as their page on event handlers to get a full list of what's available.
Another site worth checking out is You Might Not Need JQuery.
JQuery is a useful library for querying and manipulating the DOM (as well as a few other things). It's been pretty popular, so popular that a lot of developers don't know much about the browser's native ability to query and manipulate the DOM.
Recently though, there's been some movement away from using JQuery (at least using it exclusively) in favor of more structured frameworks (again, like React and Angular :) ).
By all means, check out JQuery, but I think (with this blog) I'll just skip to the good stuff and write posts about React. :)