0

Ok, so i have an unordered list and it has two items. Now in my javascript i am trying to add event listener to these items so that a CSS class can be applied to them once clicked. here is the code. can anyone fill the missing part in here.Thanks

html part:-

<body>
    <h3>Simple Add/Remove Task</h3>
    <h4>To do List</h4>
    <ul>
        <div>
            <li class="todos">Wake up</li>
            <li class="todos">Study</li>
        </div>

    <div>
        <button>Delete</button><br>
        <button>Delete</button>
    </div>
    </ul>

    <script type="text/javascript" src="./script.js"></script>
</body>

Js part:-

    var listItems = document.getElementsByClassName("todos");


for (var i = 0; i<listItems.length; i++){
    listItems[i].addEventListener("click", function(){
        
    })
}
4
  • What exactly is wrong? Please specify. Commented Jul 13, 2020 at 23:27
  • this.classList.add("yourClassNameHere");? Commented Jul 13, 2020 at 23:30
  • your HTML is invalid: <ul> can contain <li> children only. Commented Jul 13, 2020 at 23:33
  • @Kosh It can also contain script and template elements. Commented Jul 13, 2020 at 23:41

3 Answers 3

1

Just add or toggle the desired class with classList.add() or classList.toggle().

Also (FYI):

  • Headings should not be used because of the way they style the text within them. As with everything else in HTML, they are semantic. You shouldn't have an h4 unless you want a new sub-section to an h3, which you wouldn't have unless it was a sub-section of an h2 an so on. You can (and should) do your formatting with CSS, not HTML.
  • It is also invalid to put a div directly inside of a ul. Only li, script, or template elements can be children of a ul or ol.
  • Don't use .getElementsByClassName(). Use .querySelectorAll() instead.

var listItems = document.querySelectorAll(".todos");

for (var i = 0; i<listItems.length; i++){
    listItems[i].addEventListener("click", function(){
      this.classList.toggle("active");  // each click toggles the use of the class
    });
    
    // While looping over the bullets, search for the button within each
    // and set up a click handler for when the delete button gets clicked
    // .closest() will look for the nearest ancestor that matches the selector.
    listItems[i].querySelector("button").addEventListener("click", function(){
      this.closest(".todos").remove();
    });
}
h1 { font-size: 1.2em; }
h2 { font-size: 1em; }

.active { background-color:yellow; }
<h1>Simple Add/Remove Task</h1>
<h2>To do List</h2>
<ul>
  <li class="todos">Wake up <button>Delete</button></li>
  <li class="todos">Study <button>Delete</button></li>
</ul>

Sign up to request clarification or add additional context in comments.

2 Comments

Ok, so thanks for a detailed answer. i want the buttons next to both li. Should i make two divs and put ul in first one and buttons in second one? As the next function i will be adding is to delete li by delete buttons next to them.
@new2coding That really is a different question, but I have updated my answer to show that you just need to move the buttons inside of the li elements and set up a click handler on them. Please consider marking this as "the" answer and up vote all helpful answers.
0

use this line in js to change the class:

listItems[i].className = 'cssClass';

and then make some 'cssClass' css. Unless you want to make the css created in js, in which case you would do this beforehand:

var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '.cssClass { color: green; }';

1 Comment

The style element doesn't need a type="text/css" attribute any more.
0

Use for...of to iterate over the elements.

Use the event.currentTarget to get the selected element.

Use classList.add to add a class to an element

var listItems = document.getElementsByClassName("todos");

for (let listItem of listItems) {
    listItem.addEventListener("click", event => {
        event.currentTarget.classList.add('selected')
    })
}
.selected {
  background: green;
}
<body>
    <h3>Simple Add/Remove Task</h3>
    <h4>To do List</h4>
    <ul>
      <li class="todos">Wake up</li>
      <li class="todos">Study</li>
    </ul>
</body>

6 Comments

Why event.target instead of just this?
@Scott Marcus Personal preference, I find event.target easier to understand. There is also often confusion about the scope of this, especially when it comes to arrow functions.
@Scott Marcus actually event.currentTarget is a better choice here. Reflected that in my answer ;).
In this case, there would be no difference between target and currentTarget because no propagation of the event is utilized here.
@Scott Marcus Better safe than sorry ;)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.