代码之家  ›  专栏  ›  技术社区  ›  Dagon

带有哈希链接的Javascript选项卡

  •  1
  • Dagon  · 技术社区  · 2 年前

    我有5个选项卡,显示不同的内容。当你点击一个选项卡时,它应该只打开该选项卡,并将该“选项卡”的hash/id添加到URL中,这样用户就可以复制该URL,然后使用它直接转到该选项卡。带有散列的外部和内部链接的行为应该相同——打开/显示带有散列的特定选项卡。默认情况(没有散列)是打开第一个选项卡。

    我不希望链接像锚标记一样跳转到“选项卡”id。只需打开/显示“选项卡”。

    我已经创建了以下代码,除了带有哈希的内部链接不起作用之外,我可以做任何事情,如果你只是在URL中键入哈希并点击return,它也不起作用。带有哈希的外部链接工作正常。由于我正在设置窗口,防止锚“跳跃”有点小故障 scrollTo 加载页面后,页面会跳转一秒钟。我想我应该使用id标签以外的东西,这样就不会发生这种情况了?

    const tabs = document.querySelector(".wrapper");
    const tabButton = document.querySelectorAll(".tab-button");
    const contents = document.querySelectorAll(".content");
    var hash = window.location.hash.substr(1);
    
    tabs.onclick = e => {
    
      // disable scroll to
      setTimeout(function() {
        window.scrollTo(0, 0);
      }, 1);
    
      const id = e.target.dataset.id;
      const el1 = document.querySelector('button[data-id="' + id + '"]');
    
      if (id) {
        tabButton.forEach(btn => {
          btn.classList.remove("active");
        });
        el1.classList.add("active");
    
        contents.forEach(content => {
          content.classList.remove("active");
        });
        const element = document.getElementById(id);
        element.classList.add("active");
        window.location.hash = '#' + id; // update has in URL
      }
    } // end onclick
    
    if (hash) {
    
      // disable scroll to
      setTimeout(function() {
        window.scrollTo(0, 0);
      }, 1);
    
      var hashId = document.querySelector('button[data-id="' + hash + '"]');
      console.log(hashId);
    
      tabButton.forEach(btn => {
        btn.classList.remove("active");
      });
      hashId.classList.add("active");
    
      contents.forEach(content => {
        content.classList.remove("active");
      });
      var element = document.getElementById(hashId);
      element.classList.add("active");
    }
    .wrapper {
      width: 100%;
      margin: auto;
      background-color: white;
      border-radius: 10px;
      box-shadow: 0px 5px 15px rgba(0, 0, 0, .1);
      font-family: arial, helvetica, sans-serif;
    }
    
    
    /* 5 columns */
    .buttonWrapper {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
    }
    
    button {
      border: none;
      padding: 10px;
      background-color: #e6e6e6;
      color: #000;
      font-size: 18px;
      cursor: pointer;
      transition: 0.5s;
    }
    
    button:hover {
      background-color: #d4e7f4;
    }
    
    button.active {
      background-color: white;
    }
    
    .active {
      background-color: white;
    }
    
    .content {
      display: none;
      padding: 50px;
    }
    
    .content.active {
      display: block;
    }
    
    h2 .content {
      font-weight: 700;
    }
    <div class="wrapper">
      <div class="buttonWrapper">
        <button class="tab-button active" data-id="one">One</button>
        <button class="tab-button" data-id="two">Two</button>
        <button class="tab-button" data-id="three">Three</button>
        <button class="tab-button" data-id="four">Four</button>
        <button class="tab-button" data-id="five">Five</button>
      </div>
      <div class="contentWrapper">
        <div class="content active" id="one">
          <h2>Title 1</h2>
          <p>Content 1</p>
          <p><a href="#two">Link to two</a></p>
        </div>
    
        <div class="content" id="two">
          <h2>Title 2</h2>
          <p>Content 2</p>
          <p><a href="#one">Link to one</a></p>
        </div>
    
        <div class="content" id="three">
          <h2>Title 3</h2>
          <p>Content 3</p>
          <p><a href="#four">Link to four</a></p>
        </div>
    
        <div class="content" id="four">
          <h2>Title 4</h2>
          <p>Content 4</p>
          <p><a href="#five">Link to five</a></p>
        </div>
    
        <div class="content" id="five">
          <h2>Title 5</h2>
          <p>Content 5</p>
          <p><a href="#one">Link to one</a></p>
        </div>
    
      </div>
    </div>
    0 回复  |  直到 2 年前