# Getting DOM elements with JavaScript

How to target elements with JavaScript.

Once you have selected them, you can
[change their CSS classes with `classList`](/javascript-adding-and-removing-class-names-from-elements).

> ️️**2015.03.19** I just noticed that any attribute can be queried with
> `querySelectorAll`, added that to the article. **2015.04.19** Added a section
> with `querySelector` and `querySelectorAll`.

## Get element by id

```js
const el = document.getElementById('my-element')
```

[MDN article](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById).

## Get element by tag name

This gets all the divs.

```js
const els = document.getElementsByTagName('div')
```

[MDN article](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByTagName).

## Get element by class name

The following doesn't work in IE8, but is otherwise a splendid method.

```js
const els = document.getElementsByClassName('my-element')
```

[MDN article](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName).

The following works down to IE8.

```js
const els = document.querySelectorAll('.my-element')
```

[MDN article](https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelectorAll).

## Get element by name

Element that has a name attribute.

```html
<div name="hello"></div>
```

Can be queried like this:

```js
const hello = document.getElementsByName('hello')
```

## Get pretty much anything

I think `.querySelector()` and `.querySelectorAll()` are underrated compared
with how handy they are. Any element can be queried using them.

```js
// Returns a nodelist with all the elements with a class .module
document.querySelectorAll('.module')

// Returns the first element with a class .module
document.querySelector('.module')

// Returns divs with .note and .alert classes
document.querySelectorAll('div.note, div.alert')

// Returns all span elements within #thing
document.querySelectorAll('#thing > span')
```

In fact, any CSS type of selector query can be used.

> The string argument passed to querySelector must follow CSS syntax.

And both of them work down to IE8 :)

- [MDN article for `querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll).
- [MDN article for `querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)

## Get a descendant element

Just as an example, imagine a table of contents plugin that needs to be enabled
if there are any `h` tags in the `#content` section:

```js
// Grab #content and h2 elements in it
const headings = document.getElementById('content').getElementsByTagName('h2')
if (headings.length > 0) {
  // Kick off the table of contents plugin here, for example
}
```

Or even more simply with `querySelectorAll`:

```js
const headings = document.querySelectorAll('#content > h2')
if (headings) {
  // Kick off the ToC plugin here
}
```

## Get elements by an arbitrary attribute

I thought this was impossible, but `querySelectorAll` shows its power again. The
following gets elements that have `data-src` attribute:

```js
const lazyImgs = document.querySelectorAll('img[data-src]')
```

[MDN article](https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelectorAll).

## Conclusions

Native JavaScript is much faster than library methods, SitePoint has a
[good article](http://www.sitepoint.com/jquery-vs-raw-javascript-1-dom-forms/),
with benchmark results.

You might also want to see these jsperf tests
[here](http://jsperf.com/id-vs-qs-vs-tag-vs-class) and
[here](http://jsperf.com/getelementbyid-vs-getelementsbyclassname), getting
elements by ID is the fastest.
