Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Thomas Moore
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Thomas Moore
Front End Web Development Techdegree Graduate 25,371 Points

Modular JavaScript .js files for each HTML page

Hi there,

I'm taking what I've learnt so far to build a multi-page website. I've hit a question which I haven't encountered before...

My JavaScript code is written in a single script named script.js. Part of the script references an HTML element using the command:

let ul = document.getElementById('chart-controls');

The problem is this HTML element (with the ID "chart controls") only exists on one page. When the script runs on any other page, it fails to locate the item and the whole script stops running (including the bits that would otherwise work fine).

My question is: Is there any way of avoiding this? Or do I have to break out this JavaScript functionality into a separate .js file, and link it only to that particular HTML page?

Thanks very much in advance for your help!

Thomas Moore
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Thomas Moore
Front End Web Development Techdegree Graduate 25,371 Points

I should say as well, if there's any Treehouse Library content that covers this sort of thing (and other multi-page website/web app questions) I'd be extremely happy. I haven't been able to find it yet.

2 Answers

Steven Parker
Steven Parker
229,644 Points

This call itself won't break the script. It will return null if the element does not exist on the current page, which you can then test to skip the remaining code that uses ul.

Thomas Moore
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Thomas Moore
Front End Web Development Techdegree Graduate 25,371 Points

Hi there, thanks for your recommendation.

So does that mean adding a check in any and all functions that use ul (and any other variable which isn't on the page) to make sure all the values being passed in aren't 'null'?

Just trying to get my round how these sorts of things are architected. The Treehouse content is good to get a starting point, but I feel like there's nowhere that explains what the next steps are.

Steven Parker
Steven Parker
229,644 Points

It's hard to say without seeing the rest of the code, but hopefully you wouldn't need to put checks in the functions themselves if you can make sure the code that calls the function is skipped when the value is null.

Thomas Moore
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Thomas Moore
Front End Web Development Techdegree Graduate 25,371 Points

Ah, thanks for the reply -- sorry taking a while to respond, I've been away. To illustrate how those variables are used, here's a fuller code snippet.

let ul = document.getElementById('chart-controls');

function resetButtonClass(){
  let toggleItems = ul.children; 
  for (let i = 0; i < toggleItems.length; i += 1) {
    toggleItems[i].className = 'not-selected';
  }
}

ul.addEventListener('click', (e) => {
  if (e.target.tagName === 'LI') {
    resetButtonClass();
    e.target.className = 'selected';
    const filterValue = e.target.textContent.toLowerCase();
    filterProjects(filterValue);     
  }
});

Does that mean the function should be something like this?

let ul = document.getElementById('chart-controls');

if (ul !== null) {
  function resetButtonClass(){
    let toggleItems = ul.children; 
    for (let i = 0; i < toggleItems.length; i += 1) {
      toggleItems[i].className = 'not-selected';
    }
  }

  ul.addEventListener('click', (e) => {
    if (e.target.tagName === 'LI') {
      resetButtonClass();
      e.target.className = 'selected';
      const filterValue = e.target.textContent.toLowerCase();
      filterProjects(filterValue);     
    }
  });
}