简体   繁体   English

在按钮单击时将 class 添加和删除到项目集合(原版 JS)

[英]Add and remove a class to a collection of items on button click (vanilla JS)

I have 3 tabs, which I am using to switch table columns in mobile version.我有 3 个选项卡,用于在移动版本中切换表格列。 What I am trying to acheive, is to hide/show table columns clicking on suitable column button.我想要实现的是单击合适的列按钮隐藏/显示表格列。 My idea was to manipulate each column items class, which would be the same for all elements inside that column, but I got stuck, that I can't add.hidden class to a collection of items.我的想法是操作每个列项目 class,这对于该列中的所有元素都是相同的,但是我卡住了,我无法将隐藏的 class 添加到项目集合中。 Would be grateful for any advise on that.将不胜感激任何建议。 Or maybe there is a better way to manipulate tabs?或者也许有更好的方法来操作标签?

 document.addEventListener('DOMContentLoaded', function() { let tabsContainer = document.querySelector('.buynow-tabs'); let tabsButtons = tabsContainer.querySelectorAll('.buynow-tabs__tab'); let basicElements = document.querySelectorAll('.table-v4__tab-basic'); let premiumElements = document.querySelectorAll('.table-v4__tab-premium'); let eliteElements = document.querySelectorAll('.table-v4__tab-elite'); for (var i = 0; i < tabsButtons.length; i++) { tabsButtons[i].addEventListener('click', function() { let current = tabsContainer.querySelectorAll('.active'); current[0].className = current[0].className.replace(' active', ''); this.className += ' active'; if (tabsButtons[0].classList.contains('active')) { basicElements.classList.remove('hidden'); premiumElements.classList.add('hidden'); eliteElements.classList.add('hidden'); } else if (tabsButtons[1].classList.contains('active')) { basicElements.classList.add('hidden'); premiumElements.classList.remove('hidden'); eliteElements.classList.add('hidden'); } else if (tabsButtons[2].classList.contains('active')) { basicElements.classList.add('hidden'); premiumElements.classList.add('hidden'); eliteElements.classList.remove('hidden'); } }); } });
 .buynow-tabs { display: flex; }
 <div class="buynow-tabs"> <div class="buynow-tabs__item-container"> <button class="buynow-tabs__tab">Basic</button> </div> <div class="buynow-tabs__item-container"> <button class="buynow-tabs__tab active">Premium</button> </div> <div class="buynow-tabs__item-container"> <button class="buynow-tabs__tab">Elite</button> </div> </div> <table> <thead> <tr> <th class="table-v4__plans-basic">Basic</th> <th class="table-v4__plans-premium">Premium</th> <th class="table-v4__plans-elite">Elite</th> </tr> </thead> <tbody> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> </tbody> </table>

You have to iterate over the table cells with for loops and have to use the if-else-blocks inside that loops.您必须使用 for 循环遍历表格单元格,并且必须在该循环内使用 if-else-blocks。 Furthermore there was no CSS definition for the class .hidden and the selectors in your js-code were wrong ( table-v4__tab instead of table-v4__plans like in your html).此外,没有 class 的 CSS 定义.hidden并且您的 js 代码中的选择器错误( table-v4__tab而不是table-v4__plans就像您的html中一样)。

To let your hardcoded class active for "Premium" come into account after page load you can trigger the click event for the premium button with:要在页面加载后考虑您的硬编码active为“Premium”活动,您可以触发高级按钮的点击事件:

document.querySelectorAll('.buynow-tabs__tab')[1].click();

Working example :工作示例

 document.addEventListener('DOMContentLoaded', function() { const tabsButtons = document.querySelectorAll('.buynow-tabs__tab'); const cells = document.querySelectorAll('[class^=table-v4__plans]'); const basicElements = document.querySelectorAll('.table-v4__plans-basic'); const premiumElements = document.querySelectorAll('.table-v4__plans-premium'); const eliteElements = document.querySelectorAll('.table-v4__plans-elite'); for (let i = 0; i < tabsButtons.length; i++) { tabsButtons[i].addEventListener('click', function() { const current = document.querySelector('.buynow-tabs__tab.active'); current.className = current.className.replace(' active', ''); this.className += ' active'; for (let i = 0; i < cells.length; i++) { cells[i].classList.add('hidden'); } for (let i = 0; i < basicElements.length; i++) { if (tabsButtons[0].classList.contains('active')) { basicElements[i].classList.remove('hidden'); } } for (let i = 0; i < premiumElements.length; i++) { if (tabsButtons[1].classList.contains('active')) { premiumElements[i].classList.remove('hidden'); } } for (let i = 0; i < eliteElements.length; i++) { if (tabsButtons[2].classList.contains('active')) { eliteElements[i].classList.remove('hidden'); } } }); } document.querySelectorAll('.buynow-tabs__tab')[1].click(); });
 .buynow-tabs { display: flex; }.hidden { display: none; }
 <div class="buynow-tabs"> <div class="buynow-tabs__item-container"> <button class="buynow-tabs__tab">Basic</button> </div> <div class="buynow-tabs__item-container"> <button class="buynow-tabs__tab active">Premium</button> </div> <div class="buynow-tabs__item-container"> <button class="buynow-tabs__tab">Elite</button> </div> </div> <table> <thead> <tr> <th class="table-v4__plans-basic">Basic</th> <th class="table-v4__plans-premium">Premium</th> <th class="table-v4__plans-elite">Elite</th> </tr> </thead> <tbody> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> </tbody> </table>


But there is a much easier way if you add an id to each button ( basic , premium and elite ).但是,如果您为每个按钮( basicpremiumelite )添加一个 id,则有一种更简单的方法 You just need to define one var for all table cells incl.您只需要为所有表格单元格(包括)定义一个 var。 th (selected by the beginning of their class name [class^=table-v4__plans] ). th (由其 class 名称[class^=table-v4__plans]的开头选择)。 In the click handler you then just have to compare the button id ( e.target.id ) with the className of the cell to decide whether you have to add or remove the class .hidden (all that in one single for loop).在点击处理程序中,您只需将按钮 id ( e.target.id ) 与单元格的className进行比较,以确定是否必须添加或删除 class .hidden (所有这些都在一个for循环中)。

Because i presumed that the class .active is just for the script i omitted it in my second example.因为我假设 class .active仅用于脚本,所以我在第二个示例中省略了它。 If it is important for styling etc. you can of course handle it in the click handler like you did or with this compressed version:如果它对样式等很重要,你当然可以像你一样在点击处理程序中处理它,或者使用这个压缩版本:

document.querySelector('button.active').className = e.target.className;
e.target.className = 'active';

Working example :工作示例

 document.addEventListener('DOMContentLoaded', function() { const cells = document.querySelectorAll('[class^=table-v4__plans]'); document.querySelector('.buynow-tabs').addEventListener('click', function(e) { for (i = 0; i < cells.length; i++) { if (cells[i].className.includes(e.target.id)) { cells[i].classList.remove('hidden'); } else { cells[i].classList.add('hidden'); } } }); document.querySelectorAll('.buynow-tabs__tab')[1].click(); });
 .buynow-tabs { display: flex; }.hidden { display: none; }
 <div class="buynow-tabs"> <div class="buynow-tabs__item-container"> <button id="basic" class="buynow-tabs__tab">Basic</button> </div> <div class="buynow-tabs__item-container"> <button id="premium" class="buynow-tabs__tab">Premium</button> </div> <div class="buynow-tabs__item-container"> <button id="elite" class="buynow-tabs__tab">Elite</button> </div> </div> <table> <thead> <tr> <th class="table-v4__plans-basic">Basic</th> <th class="table-v4__plans-premium">Premium</th> <th class="table-v4__plans-elite">Elite</th> </tr> </thead> <tbody> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> </tbody> </table>

Like other people have pointed out, the reason why your code does not work is because you have to iterate over all the elements of your selector queries.就像其他人指出的那样,您的代码不起作用的原因是您必须遍历选择器查询的所有元素。 But I think there is a more elegant way to solve your problem:但我认为有一种更优雅的方法可以解决您的问题:

Suggestion建议

I would suggest you to alter just your style sheet when clicking the buttons instead of changing the classes of all your elements.我建议您在单击按钮时只更改样式表,而不是更改所有元素的类。 It will greatly simplify your code and remove a lot of bugs altogether.它将大大简化您的代码并完全消除许多错误。

Explanation解释

Here is an example of how you can do this:以下是如何执行此操作的示例:

First add a scriptable style sheet to the head of your document:首先将可编写脚本的样式表添加到文档的开头:

const selectedTabStyles = document.createElement('style')
document.head.appendChild(selectedTabStyles)

Then create a function to alter the stylesheet然后创建一个 function 来更改样式表

function onlyShowSelectedPlan(plan) {
  selectedTabStyles.innerHTML = `
    th, td {display: none}
    .table-v4__plans-${plan} {display: table-cell}
  ` 
}

That's it for the scripting part!这就是脚本部分! Now you can add your "plan selection" function as an onclick handler to your buttons现在您可以将您的“计划选择”function 作为 onclick 处理程序添加到您的按钮

<button onclick="onlyShowSelectedPlan('basic')">Basic</button>

Demo演示

 const selectedTabStyles = document.createElement('style') document.head.appendChild(selectedTabStyles) function onlyShowSelectedPlan(plan) { selectedTabStyles.innerHTML = `th, td {display: none}.table-v4__plans-${plan} {display: table-cell}` }
 .buynow-tabs { display: flex; }
 <div class="buynow-tabs"> <div class="buynow-tabs__item-container"> <button class="buynow-tabs__tab" onclick="onlyShowSelectedPlan('basic')">Basic</button> </div> <div class="buynow-tabs__item-container"> <button class="buynow-tabs__tab" onclick="onlyShowSelectedPlan('premium')">Premium</button> </div> <div class="buynow-tabs__item-container"> <button class="buynow-tabs__tab" onclick="onlyShowSelectedPlan('elite')">Elite</button> </div> </div> <table> <thead> <tr> <th class="table-v4__plans-basic">Basic</th> <th class="table-v4__plans-premium">Premium</th> <th class="table-v4__plans-elite">Elite</th> </tr> </thead> <tbody> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> <tr> <td class="table-v4__plans-basic">Basic</td> <td class="table-v4__plans-premium">Premium</td> <td class="table-v4__plans-elite">Elite</td> </tr> </tbody> </table>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM