【问题标题】:Writing a function to change style.display property of a div?编写一个函数来更改 div 的 style.display 属性?
【发布时间】:2021-02-10 18:40:33
【问题描述】:

我正在尝试编写一个执行以下代码而不重复自身的函数。我想根据您单击的选项卡制作显示内容的选项卡,如下所示:https://www.w3schools.com/howto/howto_js_tabs.asp 但在 HTML 中没有 onClick。我可以切换按钮的类以向它们添加活动类,但我不知道如何更改 tabcontent 的 style.display 属性。第一段代码执行我想要的,但我知道有一个更清洁的解决方案。

如何让我的 openTab 函数做我想做的事?
有没有更好的方法将事件侦听器添加到按钮?

document.getElementById("btn1").addEventListener("click", function() {
  document.getElementById("content1").className ="show";
  document.getElementById("content2").className ="tabcontent";
  document.getElementById("content3").className ="tabcontent";
});
document.getElementById("btn2").addEventListener("click", function() {
  document.getElementById("content1").className ="tabcontent";
  document.getElementById("content2").className ="show";
  document.getElementById("content3").className ="tabcontent";
});
document.getElementById("btn3").addEventListener("click", function() {
  document.getElementById("content1").className ="tabcontent";
  document.getElementById("content2").className ="tabcontent";
  document.getElementById("content3").className ="show";
});
function openTab(evt) {
    // Declare all variables
  var i, tabcontent, tablinks;

  // Get all elements with class="tabcontent" and hide them
  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
    console.log('first')
  }
      
  // Get all elements with class="tablinks" and remove the class "active"
  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }
  // Show the current tab, and add an "active" class to the button that opened the tab
 

  evt.currentTarget.className += " active";

 //this loop adds a style.display = "block" to every tabcontent class.
  for (i=0; tabcontent.length; i++) {
    tabcontent[i].style.display = "block";
  }
  //if I make the id's for all the divs "content" this line adds the style.display = "block" to 
    only the first tabcontent class

  //document.getElementById("content").style.display = "block";
  
  
}
document.getElementById("btn1").addEventListener("click", openTab);
document.getElementById("btn2").addEventListener("click", openTab);
document.getElementById("btn3").addEventListener("click", openTab);


<div class="tab-container">
  <button class="tablinks" id="btn1">Fit Guide</button>
  <button class="tablinks" id="btn2">Care</button>
  <button class="tablinks" id="btn3">Material</button>
</div>
<div id="content1" class="tabcontent">
  <p>Integer vel arcu ac dolor tincidunt dapibus..</p>
</div>
<div id="content2" class="tabcontent">
  <p>Integer vel arcu ac dolor tincidunt dapibus..</p>
</div>
<div id="content3" class="tabcontent">
  <p>Integer vel arcu ac dolor tincidunt dapibus..</p>
</div>

【问题讨论】:

    标签: javascript html css


    【解决方案1】:

    关于将事件监听器添加到类似元素的集合的问题,确实有一种更简洁的方法。您可以通过类名获取所有元素,并在向每个元素添加事件侦听器的同时迭代每个元素。如下所示:

    const buttons = [...document.getElementsByClassName("tablinks")];
    
    buttons.forEach(button => {
      button.addEventListener("click", () => {
          // Some Code Here
      });
    });
    

    需要注意的是getElementsByClassName 返回一个HTML Collection 因此将其转换为可迭代对象很重要,在我们的例子中使用扩展运算符。

    关于让选项卡显示正确内容的另一个问题,您或多或少走在正确的道路上,我只会使用 classList 代替,并且没有真正需要遍历所有元素。

    我也提供了一个示例,如果您有任何问题,请告诉我!

    const toggleActive = (buttonId) => {
      const buttonClicked = document.getElementById(buttonId);
      const currentActiveBtn = document.getElementsByClassName("active")[0];
    
      currentActiveBtn.classList.remove("active");
      buttonClicked.classList.add("active")
    
    }
    
    const toggleShow = (contentId) => {
      const contentToShow = document.getElementById(contentId);
        const currentShownContent = document.getElementsByClassName("show")[0];
      
      currentShownContent.classList.remove("show");
      contentToShow.classList.add("show")
    }
    
    const buttons = [...document.getElementsByClassName("tablinks")];
    
    buttons.forEach(button => {
      button.addEventListener("click", () => {
        toggleActive(button.id)
        
        const contentId = "content" + button.id.charAt(button.id.length - 1);
        
        toggleShow(contentId);
      });
    
    })
    .tabcontent {
      display: none;
    }
    
    .active {
      color: red;
    }
    
    .show {
      display: block
    }
    <div class="tab-container">
      <button class="tablinks active" id="btn1">Fit Guide</button>
      <button class="tablinks" id="btn2">Care</button>
      <button class="tablinks" id="btn3">Material</button>
    </div>
    <div id="content1" class="tabcontent show">
      <p>Content for Tab 1</p>
      <p>Hello World from Tab 1!</p>
    </div>
    <div id="content2" class="tabcontent">
      <p>Content for Tab 2</p>
      <p>Hello Again from Tab 2!!</p>
    </div>
    <div id="content3" class="tabcontent">
      <p>Content for Tab 3</p>
      <p>Okay Bye now!</p>
    </div>

    【讨论】:

    【解决方案2】:

    更简洁的方法是在包含所有按钮的元素上仅设置 一个 事件处理程序,并通过 事件委托 检测 click 事件(在冒泡阶段)

    let tc = document.querySelector('.tab-container');
    
    tc.addEventListener('click', function(ev) {
      let target = ev.target;
      if (target.matches('button[data-idcontent]')) {
        let idContent = target.dataset.idcontent;
        
        /* hide previous visible content (if any) */
        let prevVisible = document.querySelector('.tabcontent.visible');
        if (!!prevVisible && prevVisible.id !== idContent) {
          prevVisible.classList.remove('visible');
        }
        
        document.getElementById(idContent).classList.add('visible');
       
      }
    });
    .tabcontent:not(.visible) {
      display: none;
    }
    <div class="tab-container">
      <button class="tablinks" data-idcontent="content1">Fit Guide</button>
      <button class="tablinks" data-idcontent="content2">Care</button>
      <button class="tablinks" data-idcontent="content3">Material</button>
    </div>
    
    <div id="content1" class="tabcontent">
      <p>1 Integer vel arcu ac dolor tincidunt dapibus..</p>
    </div>
    <div id="content2" class="tabcontent">
      <p>2 Integer vel arcu ac dolor tincidunt dapibus..</p>
    </div>
    <div id="content3" class="tabcontent">
      <p>3 Integer vel arcu ac dolor tincidunt dapibus..</p>
    </div>

    仅 CSS 方法

    附带说明,如果您使用链接而不是按钮(但您始终可以设置样式链接为按钮)

    .tabcontent:not(:target) {
      display: none;
    }
    
    .tab-container a {
      display: inline-block;
      border: 1px currentColor solid;
      border-radius: 3px;
      background: #e8e8e8;
      padding: .15em .5em;
      text-decoration: none;
      color: #000;
      font: .8em Arial;
    }
    <div class="tab-container">
      <a href="#content1">Fit Guide</a>
      <a href="#content2">Care</a>
      <a href="#content3">Material</a>
    </div>
    
    <div id="content1" class="tabcontent">
      <p>1 Integer vel arcu ac dolor tincidunt dapibus..</p>
    </div>
    <div id="content2" class="tabcontent">
      <p>2 Integer vel arcu ac dolor tincidunt dapibus..</p>
    </div>
    <div id="content3" class="tabcontent">
      <p>3 Integer vel arcu ac dolor tincidunt dapibus..</p>
    </div>

    【讨论】:

      猜你喜欢
      • 2023-02-02
      • 1970-01-01
      • 1970-01-01
      • 2013-12-03
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多