48

I want to write something like this in javascript:

var all_headings = document.getElementsByTagName("h1,h2,h3,h4,h5,h6");

all_headings would then be a list of all elements that are h1 or h2 or h3... And in the order that they appear in the document, of course.

How do I do it?

Eyal
  • 5,728
  • 7
  • 43
  • 70

7 Answers7

81

With modern browsers you can do

document.querySelectorAll("h1, h2, h3, h4, h5, h6")

Or you could get cross-browser compatibility by using jQuery:

$("h1, h2, h3, h4, h5, h6")
Alex Turpin
  • 46,743
  • 23
  • 113
  • 145
  • 2
    querySelectorAll doesn't return a live list like getElementsByTagName. Does the jquery version return a live list? – Eyal Aug 17 '11 at 14:53
  • A live list is a series of pointers into the document that you can modify. For example, each element of the output of querySelectorAll() has .parent = null. Compare with getElementsByTagName where the elements have .parent set. – Eyal Aug 22 '11 at 12:22
  • Oh. Then yes, with jQuery you get the elements with all their document properties and positions set correctly. – Alex Turpin Aug 22 '11 at 13:30
  • .parentElement attributes exist for querySelectorAll results now – Shaun Lebron Oct 25 '15 at 14:07
  • @Eyal You can use `Array.from()` to make a usable array. `Array.from(document.querySelectorAll(...))` – zxbEPREF Aug 21 '18 at 17:31
21

If you are using jQuery you can use

$(":header")

example from jQuery documentation

<script>$(":header").css({ background:'#CCC', color:'blue' });</script>

Documentation

GibboK
  • 71,848
  • 143
  • 435
  • 658
9

If you're just needing some cross-browser DOM selection, there's no need to load jQuery.

Just load Sizzle instead. It's the selector engine that jQuery uses.

Example: http://jsfiddle.net/77bMG/

var headings = Sizzle('h1,h2,h3');

for( var i = 0; i < headings.length; i++ ) {
    document.write('<br>');
    document.write(i + ' is ' + headings[i].innerHTML);
}

Or without any library code, you can walk the DOM, and push the headings into an Array.

Example: http://jsfiddle.net/77bMG/1/

var headings = [];

var tag_names = {
    h1:1,
    h2:1,
    h3:1,
    h4:1,
    h5:1,
    h6:1
};

function walk( root ) {
    if( root.nodeType === 1 && root.nodeName !== 'script' ) {
        if( tag_names.hasOwnProperty(root.nodeName.toLowerCase()) ) {
            headings.push( root );
        } else {
            for( var i = 0; i < root.childNodes.length; i++ ) {
                walk( root.childNodes[i] );
            }
        }
    }
}

walk( document.body );

for( var i = 0; i < headings.length; i++ ) {
    document.write('<br>');
    document.write(i + ' is ' + headings[i].innerHTML);
}
user113716
  • 318,772
  • 63
  • 451
  • 440
3

QuentinUK's is the best answer here, as it is the /only/ one that answers the question by providing a solution using only JavaScript with no libraries.

for (i=1; i<=6; i++) {
    var headers = document.getElementsByTagName('h'+i);
    for (j=0; j<headers.length; j++) {
        headers[j].className = 'h';
    }
}
var headers = document.getElementsByClassName('h');
for (i=0; i<headers.length; i++) {
    headers[i].innerHTML += ' '+i;
}
Jan Kyu Peblik
  • 1,435
  • 14
  • 20
3

You dont need jQuery for something simple; try his:

var tags = [ "h1","h2","h3" ];
var all_headings = [];

for(var i = 0; i < tags.length; i++)
    all_headings = all_headings.concat(document.getElementsByTagName(tags[i]));
TJHeuvel
  • 12,403
  • 4
  • 37
  • 46
  • You're creating an Array that holds 3 NodeLists. Might as well just use `.push()` instead of `.concat()`. – user113716 Aug 15 '11 at 14:00
  • Doesnt concat merge the result of getElementsByTagName into all_headings? I havent really tested it. – TJHeuvel Aug 15 '11 at 14:21
  • @TJHeuvel: Unfortunately, no. You could do something like this in your `for` statement, but it still won't maintain the order in the document as required in the question, and it won't work in IE8 and lower. `all_headings.push.apply(all_headings, all_headings.slice.call(document.getElementsByTagName(tags[i])));` – user113716 Aug 15 '11 at 16:52
2

Function without jQuery and document.querySelectorAll

function get_all_h(document) {
    var arr = [];
    if (!document) return arr;
    var all_el = document.getElementsByTagName('*');
    for (var i = 0, n = all_el.length; i < n; i++) {
        if (/^h\d{1}$/gi.test(all_el[i].nodeName)) {
            arr.push(all_el[i]);
        }
    }
    return arr;
}
Ramil Shavaleev
  • 364
  • 3
  • 12
0

Give them a common class name then use getElementsByClassName

Mi-Creativity
  • 9,554
  • 10
  • 38
  • 47
QuentinUK
  • 2,997
  • 21
  • 20