Javescript Uncaught TypeError: pageBody.style is undefined

I am trying to do a little Javascript project, still fairly new to the script, I have been following along with this guide I am using but for some reason none of the code I use works, though I copy it straight from the book. Any help would be greatly appreciated thank you

<!DOCTYPE html>
<html>
	<head>
		<script>

			var pageBody = document.getElementsByTagName('body');

			pageBody.style.fontFamily = "Arial, sans-serif";

			var nickName = document.getElementById('nickname');
			var favorites = document.getElementById('favorites');
			var homeTown = document.getElementById('homeTown');

			nickName.innerHTML +='Joey'
			favorites.innerHTML +='A very oepn question, I like games if you mean favorite things.'
			homeTown.innerHTML +='Nantwich'
		</script>
    	<meta charset="utf-8"/>
    	<title>About Me</title>
	</head>
	<body>
		<h1>About Me</h1>

	    <ul>
	    	<li>Nickname:
	    		<span id="nickname"></span>
	    	</li>
	   		<li>Favorites:
	    		<span id="favorites"></span>
	    	</li>
	    	<li>Hometown:
	     		<span id="hometown"></span>
	    	</li>
	   	</ul>
	   
	</body>

</html>
1 Like

I would expect this:

var pageBody = document.getElementsByTagName('body');

to return an array, “Elements” is plural.

Just as general debugging, I would put:

console.log(pageBody);

on the line after and see what you get. That would have been my first step.

As said, getElementsByTagName returns an HTMLCollection (array like). Maybe you are missing the [0] at the end.

Anyway, I would suggest using querySelector (and querySelectorAll where appropriate) instead.

1 Like

Or, when selecting the body, simply get it directly: html defines document as having two direct child nodes. document.head and document.body.

As has been said, there are different mechanisms for finding nodes within the DOM, and which you use depends on your need. In this case, where it’s a known point and the only one, either the direct selector (document.body) or querySelector work equally well.

If you needed to act on multiple elements (adding an action to all buttons, or adding features to all text input elements), the getElementsByClassName, getElementsByTagName or querySelectorAll will provide you with an array (or “array-like”) structure.

Of course, all this overlooks the fact that your script is running before the body has loaded, and before any of your selections actually exist…

I might either add the attribute defer to your script tag, or move it to just before the closing </body> tag.

1 Like

True, I didn’t even really look at the code, to be honest.

You also have an id hometown but the getElementById selector is looking for homeTown.


Seems a bit odd if this code is from a book that it would be structured like this but maybe it’s just part of the code and not how you were told to use it.

3 Likes

Adding the [0} has seemed to have worked. I have kept the format .getElementsByTagName purely so the marking software can pick up that I have used the code I have learnt, thanks for the suggestion.

I moved it to the bottom as suggested and with the addition of [0] it has worked, thank you all for your notes and suggestions. I will keep someof the otehr stuff you have mentioned in mind for when I have progressed further. Unfortunatly, these challenges aren’t about the best code, its about having the code they elements they have asked. to see. Thank you all again