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

Help on dom manipulation code causing unexpected errors and not working

Hello, I recently just finished the DOM course on Treehouse and started creating a little personal project in workspaces to review what I learned. It is basically a todo list app but with multiple pages of features where you can have an agenda, a timer page, and other stuff. I have a menu on the side with buttons for the pages that when one is clicked, it will run a function for that page specified by the button that adds some elements to an area of the page where the app is. When creating this though, I get some unexpected errors and things not working. Since in my HTML file the page buttons are divs, I had to add a CSS rule to make the cursor be a pointer. After I finished my js, the pointer cursor disappears when I hover over the divs. I have tried to fix this and look over my code but nothing has worked. I have 2 other problems in that same click event listener which might correlate to the cursor problem. The first is that I have created a bunch of if statements with the purpose of that it filters out the page button that is clicked and makes its text bold to indicate which page you are on and the other page buttons text weight stays the same normal value. I did this to make sure that when you click a button and it makes its text bold then you click another button, it makes that new clicked button bold and makes the other buttons text go back to normal. This is not working. The second problem is that in my click event listener I filter which part of the button is clicked like the general div space, the icon, or the text of the button and I traverse the DOM for each element to bold the text and run the function for that corresponding page. When I click on the text or icon, this code works but when I click on the space and padding of the div, nothing happens so it does not work. If you can help thank you so much.

Here is the link to my workspace:

https://w.trhou.se/4uhggm4wwo

Thank you for your time!

Steven Parker
Steven Parker
231,236 Points

To share a workspace, make a snapshot of your workspace and post the link to it here.

Ok I updated it thanks steven

2 Answers

Steven Parker
Steven Parker
231,236 Points

It looks like there are a number of issues in "main.js":

  • lines 14-17 are attempting to index a single element, the function should be "querySelectorโ€All"
  • line 45 always changes weight
  • line 47 causes an undefined function error for any button except "Timebox"
  • line 48 should use the length of the collection as the limit
  • lines 51 and 53 should reference the element itself instead of the text attribute
  • more issues like the above in the repeated similar code sections (code could also be more "DRY") ```

Your response helped a lot but now no buttons show up bold. Here is the updated event listener code:

pageButtons.addEventListener('click', (event) => {
   if (this.className == "menu-pages-todo") {
     const buttonSpanChild = this.children[1];
     const spanText = buttonSpanChild.textContent;
     functions[spanText]();
     for (let n=0; n < pageButtonDivs.length; n++) {
        const eachSpanText = buttonSpanChild.textContent;
        if (eachSpanText !== spanText) {
              buttonSpanChild.style.fontWeight = "200";
            } else {
              buttonSpanChild.style.fontWeight = "600";
            }
     }
    } else if (this.tagName == 'SPAN') {
        const spanText2 = this.textContent;
        functions[spanText2]();
        for (let i=0; i < pageButtonDivs.length; i++) {
        const eachSpanText2 = pageButtonDivs[i].children[1].textContent;
        if (eachSpanText2 !== spanText2) {
              this.style.fontWeight = "200";
            } else {
              this.style.fontWeight = "600";
            }
        }
      } else {
        const span = this.nextElementSibling;
        const spanText3 = span.textContent;
        functions[spanText3]();
        for (let x=0; x < pageButtonDivs.length; x++) {
        const eachSpanText3 = pageButtonDivs[x].children[1].textContent;
        if (eachSpanText3 !== spanText3) {
              span.style.fontWeight = "200";
            } else {
              span.style.fontWeight = "600";
            }
        }
      }
    });
Steven Parker
Steven Parker
231,236 Points

Looks like you did more than just implement the hints; in particular, changing the "target" references to "this". Only conventional functions establish "this" as a reference to the target, arrow functions don't.

You might also want to give some thought to what the "else" clause does. If the item clicked doesn't have the class name of "menu-pages-todo" and it is not a "span", what might it (and the next sibling) be?

This might be an excellent time to get familiar with debugging features of the built-in browser tools. Have you done the Debugging JavaScript in the Browser workshop?

Thank you steven for your help and suggestions. I did the Debugging Javascript in the Browser and I solved the problem! The event listener should have just been on an indiviual button div. Whenever the listener was fired "this" would always be the parent element of all of the buttons and the reason the else clause was not working is because it was selecting the next element of ALL of the buttons, a separation div with no text of course.

Thank you steven for all of the great feedback you give on treehouse constantly.

Steven Parker
Steven Parker
231,236 Points

Thanks for the nice comments. But did you mean to select your own response as "best answer"? :see_no_evil:

Haha I changed it