【问题标题】:Close open tab on click with vanilla javascript使用香草javascript单击关闭打开的选项卡
【发布时间】:2021-03-31 16:39:49
【问题描述】:

我一直在尝试构建一个标签系统,其中标签在点击时关闭。当我尝试关闭一个打开的标签时,它仍然保持打开状态。

基本上,当我单击一个选项卡时,该选项卡会打开,而当我单击同一个打开的选项卡时,该选项卡应该会关闭。这就是我一直在努力实现的目标。

尝试使用 toggle() 方法在目标选项卡上打开和关闭 .active 类,如下所示:

this.classList.toggle("active");

但是这似乎没有任何作用,因为单击的选项卡始终保持打开状态。

我相信这是一件非常简单的事情,但我就是想不通。

我会很感激一些帮助。干杯!

const tabs = document.querySelectorAll(".tab");
const tabContents = document.querySelectorAll(".tab-content");

for (let i = 0; i < tabs.length; i++) {
    const tab = tabs[i];
    tab.addEventListener("click", switchClass);
}

function switchClass() {
    for (let i = 0; i < tabs.length; i++) {
        const tab = tabs[i];
        tab.classList.remove("active");
    }

    for (let i = 0; i < tabContents.length; i++) {
        const tabContent = tabContents[i];
        tabContent.classList.remove("show-content");
    }

    this.classList.toggle("active");

    const tabDataAttribute = this.getAttribute("data-content");
    document
        .querySelector(`.tab-content[data-content="${tabDataAttribute}"]`)
        .classList.add("show-content");
}
ul {
    margin: 0;
    padding: 0;
}

.tab {
    display: inline-block;
    border: 1px solid lightgrey;
    padding: 10px;
    cursor: pointer;
}

.active {
    background: lightgrey;
}

.tab-content {
    display: none;
    padding: 10px;
}

.show-content {
    display: block;
    background: lightgray;
}
<ul>
    <li class="tab" data-content="tab1">Tab 1</li>
    <li class="tab" data-content="tab2">Tab 2</li>
    <li class="tab" data-content="tab3">Tab 3</li>
</ul>

<div class="tab-content" data-content="tab1">1. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
<div class="tab-content" data-content="tab2">2. Vivamus iaculis est in sapien congue, ac condimentum.</div>
<div class="tab-content" data-content="tab3">3. Phasellus aliquam orci neque, non varius quam gravida vel.</div>

【问题讨论】:

  • 似乎在这里工作得很好。
  • 当我点击一个打开的标签时它并没有关闭它。
  • 您在 Stack Overflow 中尝试过吗?它工作得很好。
  • 例如点击 Tab 1。它会变得活跃对吗?现在单击同一选项卡将其关闭。它将保持开放。那就是问题所在。我希望能够单击打开的选项卡并关闭它。
  • 我明白了。查看我的答案以获取解决方案。

标签: javascript tabs toggle


【解决方案1】:

您不能使用.toggle(),因为您在回调中做的第一件事是从所有元素中删除active 类(这是正确的做法),因此切换只会将其重新打开(如是目前的情况)。

相反,您必须跟踪当前单击的选项卡是否与上次单击的选项卡相同并采取相应措施。

在下面的代码中,我还组合了循环并使用.forEach() 循环语法而不是计数循环,因为.forEach() 更简单。

而且,除非您有其他需要,否则您不再需要 data-content 属性。

const tabs = Array.from(document.querySelectorAll(".tab"));
const tabContents = document.querySelectorAll(".tab-content");

// Use the Array.forEach() syntax for looping as it eliminates
// the need for setting up and managing indexes.
tabs.forEach(function(tab){
  tab.addEventListener("click", switchClass);
});

let priorActive = null;  // Will keep track of last tab made active

function switchClass() {
  // Loop over the tabs
  tabs.forEach(function(tab, index){
    tab.classList.remove("active");             // Remove active
    tabContents[index].classList.add("hidden"); // Hide content with corresponding index
  });

  // Can't use toggle because prior loop just removed the classes, so toggle
  // will always add them back. Instead, you must explicitly turn on or off
  // based on current situation.
  if(priorActive === this){
    this.classList.remove("active");  
    tabContents[tabs.indexOf(this)].classList.add("hidden");
    priorActive = null;
  } else {
    this.classList.add("active");  
    tabContents[tabs.indexOf(this)].classList.remove("hidden");  
    priorActive = this;
  }
}
ul {
    margin: 0;
    padding: 0;
}

.tab {
    display: inline-block;
    border: 1px solid lightgrey;
    padding: 10px;
    cursor: pointer;
}

.active {
    background: lightgrey;
}

.tab-content {
    background: lightgray;
    padding: 10px;
}

/* Tab content will have this by default  */
.hidden {
  display:none;
}
<ul>
    <li class="tab">Tab 1</li>
    <li class="tab">Tab 2</li>
    <li class="tab">Tab 3</li>
</ul>

<div class="tab-content hidden">1. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
<div class="tab-content hidden">2. Vivamus iaculis est in sapien congue, ac condimentum.</div>
<div class="tab-content hidden">3. Phasellus aliquam orci neque, non varius quam gravida vel.</div>

【讨论】:

    猜你喜欢
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 2021-12-29
    相关资源
    最近更新 更多