1

正如标题所述,我正在制作一个选项卡式部分,以在单击时切换内容,效果很好,我怎样才能使它在单击新选项卡时可以平滑过渡到内容并防止跳转到顶部每次我点击一个标签页?

我尝试添加阻止链接的功能,但这不是链接,因此似乎不起作用。

HTML

 <section class="featured-books">
        <div class="featured-books-title"><h2>Featured Books</h2></div>
        <ul class="tabs">
            <li data-tab-target="#featured" class="active tab">Featured</li>
            <li data-tab-target="#on-sale" class="tab">On Sale</li>
            <li data-tab-target="#most-viewed" class="tab">Most Viewed</li>
        </ul>
        <div id="featured" data-tab-content class="active">
            <div class="featured-tab">
                <img src="./images/12-rules.jpg">
                <img src="./images/7-habits.jpg">
                <img src="./images/art-of-war.jpg">
                <img src="./images/boundaries.jpg">
                <img src="./images/unlimited-memory.jpg">
                <img src="./images/meaning-of-marriage.jpg">
                <img src="./images/meditations.jpg">
                <img src="./images/peaceful-parents.jpg">
                <img src="./images/plant-paradox.jpg">
                <img src="./images/spirit-filled-life.jpg">
                <img src="./images/javascript-definitive-guide.jpg">
                <img src="./images/atomic-habits.jpg">
            </div>
        </div>
        <div id="on-sale" data-tab-content>
        </div>
        <div id="most-viewed" data-tab-content>
        </div>
    </section>

CSS

.featured-books h1 {
    display: flex;
    justify-content: center;
}

[data-tab-content] {
    display: none;
}
    
.active[data-tab-content] {
    display: block;
}
    
.tabs {
    display: flex;
    justify-content: center;
    list-style-type: none;
    margin: 0;
    padding-bottom: 60px;
    padding-top: 16px;
}


.tab {
    border-radius: 20px;
    cursor: pointer;
    padding: 10px;
}

.tab.active {
    background-color: #CCC;
}

.tab:hover {
    background-color: #aaa;
}



/**------FEATURED TAB CONTENT------*/

.featured-tab {
    position: absolute;
    justify-content: center;
    align-items: center;
    margin-top: 10px;
    width: 100vw;
    display: grid;
    grid-template-columns: repeat(auto-fill,minmax(300px,300px));
    column-gap: 3px;
    row-gap: 40px;
  }
  
  .featured-tab img {
    width: 180px;
    height: auto;
    object-fit: cover;
    object-position: center;
  } 

JavaScript

const tabContents = document.querySelectorAll('[data-tab-content]')
  
  tabs.forEach(tab => {
    tab.addEventListener('click', () => {
      const target = document.querySelector(tab.dataset.tabTarget)
      tabContents.forEach(tabContent => {
      tabContent.classList.remove('active')
    })
    tabs.forEach(tab => {
      tab.classList.remove('active')
    })
    tab.classList.add('active')
    target.classList.add('active')
  })
}) 
4

1 回答 1

0

这是一个使用不透明度过渡的简单示例,但您可以根据需要使用高度、宽度或变换。我使用 aria-attributes 来跟踪诸如打开的文章以及文章中的信息是否应该被屏幕阅读器读取。两个最重要的 CSS 类是显示和隐藏。这些控制不透明度以及何时发生过渡。显示有轻微的延迟,所以它等待被隐藏的人让开。就 JavaScript 而言。

  1. 选择所有有弹出窗口的按钮。
  2. 创建一个事件监听器来处理点击。
  3. 选择受控文章和所有文章。
  4. 检查受控物品当前是否隐藏。
  5. 如果是隐藏所有的文章。
  6. 将所有按钮 aria-expanded 属性更改为 false。
  7. 将单击按钮上的 aria-expanded 属性设置为 true。
  8. 将受控物品上的 aria-hidden 类设置为 false。
  9. 移除 hide 类并将 show 类添加到受控物品。

const buttons = document.querySelectorAll("[aria-haspopup=true]")

const handleClick = (event) => {
  const controls = event.target.getAttribute("aria-controls"),
  controlled = document.getElementById(controls),
  articles = document.querySelectorAll("article");
  if (controlled.getAttribute("aria-hidden") === "true") {
    articles.forEach(article => {
      article.setAttribute("aria-hidden", "true");
      article.classList.add("hide");
      article.classList.remove("show");
    })
    buttons.forEach(button => button.setAttribute("aria-expanded", "false"))
    event.target.setAttribute("aria-expanded", "true");
    controlled.setAttribute("aria-hidden", "false");
    controlled.classList.remove("hide");
    controlled.classList.add("show");
  }
}

buttons.forEach(button => {
  button.addEventListener("click", handleClick);
})
ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
}

li {
  margin-right: 10px;
}

article {
  height: calc(100vh - 50px);
  width: 100vw;
  position: absolute;
  top: 50px;
  left: 0;
}

#feature {
  background-color: red;
}

#sale {
  background-color: green;
}

#view {
  background-color: blue;
}

.show {
  opacity: 1;
  transition: opacity .2s ease-in-out .2s;
}

.hide {
  opacity: 0;
  transition: opacity .2s ease-in-out;
}

button[aria-expanded=true] {
  background-color:  #cceeff;
}
<ul>
  <li>
    <button aria-haspopup="true" aria-expanded="true" aria-controls="feature">Featured</button>
  </li>
  <li>
    <button aria-haspopup="true" aria-expanded="false" aria-controls="sale">On Sale</button>
  </li>
  <li>
    <button aria-haspopup="true" aria-expanded="false" aria-controls="view">Most Viewed</button>
  </li>
</ul>
<article class="show" id="feature" aria-hidden="false">
  <h1>Featured</h1>
</article>
<article class="hide" id="sale" aria-hidden="true">
  <h1>On Sale</h1>
</article>
<article class="hide" id="view" aria-hidden="true">
  <h1>Most Viewed</h1>
</article>

于 2022-02-10T13:16:25.247 回答