CSS类添加到多个li元素点击-如何限制到点击li只?

jqjz2hbq  于 2023-10-21  发布在  其他
关注(0)|答案(7)|浏览(121)

我试图在ul列表中添加一个CSS类到一个被点击的li元素中,但是我遇到了一个问题,CSS类被添加到多个li元素中,而不是被点击的那个。我想点击一个li,颜色适用于点击的li这是我使用的代码:

const lis = document.querySelectorAll('.li');
lis.forEach((li)=>{
    li.addEventListener("click",()=>{
        li.classList.add('active')
    })
})
ul {
    list-style: none;
    display: flex;
    justify-content: center;
  }
  
  .li {
    margin: 0 0.5rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid black;
    border-radius: 0.25rem;
    cursor: pointer;
  }
  
  .li:hover {
    background-color: #ccc;
  }
  .li.active{
    color: red;
  }
<body>
    <ul>
        <li class="li">1</li>
        <li class="li">3</li>
        <li class="li">4</li>
        <li class="li">5</li>
        <li class="li">6</li>
        <li class="li">7</li>
    </ul>
</body>

当我点击一个li元素时,“active”类被添加到列表中所有已经点击的li元素中,而不仅仅是被点击的那个。我如何修改这段代码来确保“active”类只被添加到被单击的li元素中,而不添加到列表中的任何其他元素中?
任何帮助或指导将不胜感激。谢谢你,谢谢!

bd1hkmkf

bd1hkmkf1#

更新代码并使用target。你必须从以前的li中删除活动类。
下面是完整的代码:

const lis = document.querySelectorAll('.li');
lis.forEach((li)=>{
  li.addEventListener("click",(e)=>{
      document.querySelector('.active')?.classList.remove('active');
      e.currentTarget.classList.add('active');
  });
});
ul {
    list-style: none;
    display: flex;
    justify-content: center;
  }
  
  .li {
    margin: 0 0.5rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid black;
    border-radius: 0.25rem;
    cursor: pointer;
  }
  
  .li:hover {
    background-color: #ccc;
  }
  .li.active{
    color: red;
  }
<ul>
        <li class="li">1</li>
        <li class="li">3</li>
        <li class="li">4</li>
        <li class="li">5</li>
        <li class="li">6</li>
        <li class="li">7</li>
    </ul>

第一行:

document.querySelector('.active')?.classList.remove('active');

它将选择具有活动类的元素,然后从其中删除活动类。我使用?,它将首先检查是否有任何活动元素可用,如果它可用,它将从它中删除活动类。如果它不可用,它不会抛出错误。
第二行:

e.currentTarget.classList.add('active');

它将简单地在当前单击的元素上添加活动类。

0g0grzrc

0g0grzrc2#

将“click”事件注册到单个祖先元素(即包含所有可单击元素的元素(例如,所有<li>))。创建一个事件处理程序,它将对特定的元素被点击做出React(例如,在点击任何<li>时切换".active")。这种编程范式称为事件委托。
该示例的行为如下所示:

  • 如果用户单击了一个包含".active"<li>,则删除它,否则添加".active"
  • 一次只有一个<li>可以有".active"
  • 如果用户单击其他任何内容,则".active"(如果存在)将被删除。

触发已注册事件时调用的函数

示例中有详细注解

/*
Register the "click" event to Document Object.
When user clicks anywhere on the page, call setActive().
*/
document.onclick = setActive;

/*
Event handler passes the (event) Object by default.
*/
function setActive(event) {
  /*
  Reference the element that the user clicked.
  */
  const clicked = event.target;
  /*
  Collect all <li> into a NodeList and convert it into an array.
  */
  const liArray = [...document.querySelectorAll("li")];
  /*
  Determine the index number of the element the user clicked.
  If the user clicked a <li>, it will be a number between 0 to 6.
  Otherwise it'll be -1.
  */
  let position = liArray.indexOf(clicked);
  /*
  Iterate through 'liArray'... 
  */
  liArray.forEach((li, index) => {
    /*
    If current 'index' DOES NOT EQUAL 'position'...
    */
    if (index !== position) {
      /*
      Remove ".active" from current <li>
      */
      li.classList.remove("active");
    }
  });

  /*
  If the element the user clicked is a <li>...
  */
  if (clicked.matches("li")) {
    /*
    ...add/remove (ie toggle) ".active" to it.
    */
    clicked.classList.toggle("active");
  }
}
html {
  font: 2ch/1.2 "Segoe UI";
}

ul {
  width: min-content;
  color: white;
  background: black;
}

li {
  padding: 5px 10px 5px 5px;
  margin-bottom: 5px;
}

.active {
  outline: 3px solid cyan;
  color: cyan;
  background: black;
}
<ul>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
  <li>ITEM</li>
</ul>
webghufk

webghufk3#

const lis = document.querySelectorAll('.li');
lis.forEach((li)=>{
  li.addEventListener("click",(e)=>{
      document.querySelector('.active')?.classList.remove('active');
      e.currentTarget.classList.add('active');
  });
});
ul {
    list-style: none;
    display: flex;
    justify-content: center;
  }
  
  .li {
    margin: 0 0.5rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid black;
    border-radius: 0.25rem;
    cursor: pointer;
  }
  
  .li:hover {
    background-color: #ccc;
  }
  .li.active{
    color: red;
  }
<ul>
        <li class="li">1</li>
        <li class="li">3</li>
        <li class="li">4</li>
        <li class="li">5</li>
        <li class="li">6</li>
        <li class="li">7</li>
    </ul>
thtygnil

thtygnil4#

如果你的意思是只想激活点击的项目,你可以像这样修改你的js代码。

const lis = document.querySelectorAll('.li');
const setActive= (li) => {
    Array.from(lis).forEach((item) => {
        item.classList.remove("active");
    });
    li.classList.add('active')
}
lis.forEach((li)=>{
    li.addEventListener("click",()=>{
        setActive(li)
    })
})
ql3eal8s

ql3eal8s5#

根据你最初的问题,你的代码按预期工作。
根据您的评论,如果您想从以前的li中删除.active类,试试这个:

const lis = document.querySelectorAll('.li');
lis.forEach((li) => {
  li.addEventListener("click", () => {
    // remove active class from all li
    lis.forEach(l => l.classList.remove('active'))
    
    // add active to current li
    li.classList.add('active')
    
  })
})
ul {
  list-style: none;
  display: flex;
  justify-content: center;
}

.li {
  margin: 0 0.5rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid black;
  border-radius: 0.25rem;
  cursor: pointer;
}

.li:hover {
  background-color: #ccc;
}

.li.active {
  color: red;
}
<body>
  <ul>
    <li class="li">1</li>
    <li class="li">3</li>
    <li class="li">4</li>
    <li class="li">5</li>
    <li class="li">6</li>
    <li class="li">7</li>
  </ul>
</body>
ou6hu8tu

ou6hu8tu6#

您可以轻松地删除所选li的类

document.querySelector('li.active')?.classList.remove('active');
li.classList.add('active');

或者你可以只使用html和css,避免使用JavaScript。

ul.pages {
  list-style: none;
  display: flex;
  justify-content: center;
}

ul.pages li label{
  margin: 0 0.5rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid black;
  border-radius: 0.25rem;
  cursor: pointer;
}

ul.pages li:hover label{
  background-color: #ccc;
}

ul.pages input:checked + label {
  color: red;
}

ul.pages input {
  display: none;
}
<ul class="pages">
  <li><input type="radio" name="pg" id="pg1"><label for="pg1">1</label></li>
  <li><input type="radio" name="pg" id="pg2"><label for="pg2">2</label></li>
  <li><input type="radio" name="pg" id="pg3"><label for="pg3">3</label></li>
  <li><input type="radio" name="pg" id="pg4"><label for="pg4">4</label></li>
  <li><input type="radio" name="pg" id="pg5"><label for="pg5">5</label></li>
  <li><input type="radio" name="pg" id="pg6"><label for="pg6">6</label></li>
  <li><input type="radio" name="pg" id="pg7"><label for="pg7">7</label></li>
</ul>
px9o7tmv

px9o7tmv7#

从当前li.active中删除类(如果存在)。这里是一个使用event delegation的解决方案,所以你需要一个处理函数。

document.addEventListener(`click`, handle);

// For fun: the advantage of event delegation is that 
// you're able to add elements without having to assign 
// a new handler to it.
insertMissing();

function handle(evt) {
  if (evt.target.closest(`li`)) {
    document.querySelector(`li.active`)?.classList.remove(`active`);
    return evt.target.closest(`li`).classList.add(`active`);
  }

  return true;
}

function insertMissing() {
  const nwLi = Object.assign(
    document.createElement(`li`), {
      className: `li`,
      innerHTML: `<b>2</b>`
    });
  document.querySelector(`ul li:first-child`)
    .insertAdjacentElement(`afterend`, nwLi);
}
ul {
  list-style: none;
  display: flex;
  justify-content: center;
}

.li {
  margin: 0 0.5rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid black;
  border-radius: 0.25rem;
  cursor: pointer;
}

.li:hover {
  background-color: #ccc;
}

.li.active {
  color: red;
}
<ul>
  <li class="li">1</li>
  <li class="li">3</li>
  <li class="li">4</li>
  <li class="li">5</li>
  <li class="li">6</li>
  <li class="li">7</li>
</ul>

相关问题