Javascript需要简化 - 可折叠标签

问题描述 投票:0回答:3

我编写了一些标签,它似乎运行良好,虽然我确信我可以用更清晰的代码实现这一点!我现在还不确定该怎么做。我真的很感激这个帮助。

我不确定我想要使用它的循环还是完全不同的东西?

我完成它的方式显然有效,但它看似不必要和杂乱,在此之后,下一步是在标签下降时添加过渡效果。我不确定这是否会让我这样做。

function myFunction() {
  var a = document.getElementById("results1");
  var b = document.getElementById("results2");
  var c = document.getElementById("results3");
  var d = document.getElementById("title1"); 
  var e = document.getElementById("title2"); 
  var f = document.getElementById("title3"); 
  if (a.style.display === "none") {
    a.style.display = "block";
    b.style.display = "none";
    c.style.display = "none";
    d.style.backgroundColor = "#005FAA";
    e.style.backgroundColor = "lightgrey";
    f.style.backgroundColor = "lightgrey";
  } 
  else {
    a.style.display = "none";
    d.style.backgroundColor = "lightgrey";
  }
}

function myFunction1() {
  var a = document.getElementById("results1");
  var b = document.getElementById("results2");
  var c = document.getElementById("results3");
  var d = document.getElementById("title1"); 
  var e = document.getElementById("title2"); 
  var f = document.getElementById("title3"); 
  if (b.style.display === "none") {
    a.style.display = "none";
    b.style.display = "block";
    c.style.display = "none";
    d.style.backgroundColor = "lightgrey";
    e.style.backgroundColor = "#005FAA";
    f.style.backgroundColor = "lightgrey";
  } 
  else {
    b.style.display = "none";
    e.style.backgroundColor = "lightgrey";
  }
}

function myFunction2() {
  var a = document.getElementById("results1");
  var b = document.getElementById("results2");
  var c = document.getElementById("results3");
  var d = document.getElementById("title1"); 
  var e = document.getElementById("title2"); 
  var f = document.getElementById("title3"); 
  if (c.style.display === "none") {
    a.style.display = "none";
    b.style.display = "none";
    c.style.display = "block";
    d.style.backgroundColor = "lightgrey";
    e.style.backgroundColor = "lightgrey";
    f.style.backgroundColor = "#005FAA";
  } 
  else {
    c.style.display = "none";
    f.style.backgroundColor = "lightgrey";
  }
}
body{
margin: 10px;}

.title{
background-color:lightgrey;
width: 32%;
float: left;
text-align: center;
text-decoration:none;
color:white;
margin-right: 2%;
padding: 30px;
box-sizing: border-box;
}


.title:last-child{
margin-right:0px;
width:32%;}

.results{
background-color:#005FAA;
float:left;
width: 100%;
color: white;
padding: 30px;
box-sizing: border-box;
}
<div class="container">
    <div id="title1" class="title" onclick="myFunction()">
        <h4>Item 1</h4>
    </div> 
    <div id="title2" class="title" onclick="myFunction1()">
        <h4>Item 2</h4>
    </div> 
    <div id="title3" class="title" onclick="myFunction2()">
        <h4>Item 3</h4>
    </div> 
</div>


<div class="results" id="results1" style="display:none;">Item 1</div>
<div class="results" id="results2" style="display:none">Item 2</div>
<div class="results" id="results3" style="display:none">Item 3</div>
javascript html css collapse
3个回答
0
投票

也许是这样的?你已经在使用JQuery了,所以也许让它模块化并用它来帮助你的过渡效果(你可以根据自己的喜好过渡它们)。

const tabs = {
  animating: false,
  toggleResults: function(thatTab) {
    const thatResult = $(`[data-title="${thatTab.attr('id')}"]`);
    thatTab.toggleClass('activeTab');
    thatResult.toggleClass("openedResult");
    tabs.animating = true;
    thatResult.slideToggle("fast", function() {
      tabs.animating = false;
    });
  },
  init: function() {
    $(".title").click(function() {
      const thatTab = $(this);
      const openedResult = $('.openedResult');
      const thatTabId = thatTab.attr("id");
      const openedResultTitle = openedResult.data('title');

      if (!tabs.animating) {
        $('.activeTab').removeClass('activeTab');
        openedResult.removeClass('openedResult').hide();
        if (thatTabId !== openedResultTitle) {
          tabs.toggleResults(thatTab);
        }
      }
    });
  }
};

$(function() {
  tabs.init();
});
body {
  margin: 0;
}

.container {
  display: flex;
  justify-content: space-between;
  width: 100%;
}

.title {
  background-color: lightgrey;
  flex-basis: 32%;
  transition: background-color 0ms;
  text-align: center;
  color: white;
  padding: 30px;
  box-sizing: border-box;
}

.activeTab {
  background-color: #005faa;
  transition: background-color 100ms;
}

.results {
  background-color: #005faa;
  display: none;
  width: 100%;
  color: white;
  padding: 30px;
  box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="container">
  <div id="title1" class="title">
    <h4>Item 1</h4>
  </div>
  <div id="title2" class="title">
    <h4>Item 2</h4>
  </div>
  <div id="title3" class="title">
    <h4>Item 3</h4>
  </div>
</div>


<div class="results" data-title="title1">Item 1</div>
<div class="results" data-title="title2">Item 2</div>
<div class="results" data-title="title3">Item 3</div>

0
投票

试试这个,你可以在所有三个div上调用相同的函数,并传递它们的id来查找当前的id。

<!DOCTYPE html>
<style type="text/css">

body{
margin: 10px;}

.title{
background-color:lightgrey;
width: 32%;
float: left;
text-align: center;
text-decoration:none;
color:white;
margin-right: 2%;
padding: 30px;
box-sizing: border-box;
}


.title:last-child{
margin-right:0px;
width:32%;}

.results{
background-color:#005FAA;
float:left;
width: 100%;
color: white;
padding: 30px;
box-sizing: border-box;
}

.active{
  display = "block"
}
.inactive{
  display : "none"
  backgroundColor:"#005FAA"
}

</style>

<div class="container">
    <div id="title1" class="title" onclick="ActivateTab(1)">
        <h4>Item 1</h4>
    </div> 
    <div id="title2" class="title" onclick="ActivateTab(2)">
        <h4>Item 2</h4>
    </div> 
    <div id="title3" class="title" onclick="ActivateTab(3)">
        <h4>Item 3</h4>
    </div> 
    <button onclick="ActivateTab(2)">Test</button>
</div>


<div class="results" id="results1" style="display:none;">Item 1</div>
<div class="results" id="results2" style="display:none">Item 2</div>
<div class="results" id="results3" style="display:none">Item 3</div>

<script> 

function ActivateTab(id){
  let results = document.querySelectorAll(".results")
  let titles = document.querySelectorAll(".title")

  results.forEach((elementResut,index) =>{
    let elementTitle = titles[index];
      if(elementResut.id === "results"+id 
      && elementResut.style.display === "none")
      {
            elementResut.style.display = "block";
            elementTitle.style.backgroundColor = "#005FAA";
      }
      else{
        elementResut.style.display = "none";    
        elementTitle.style.backgroundColor = "lightgrey";
      }
  }); 
}

</script>

0
投票

这是一个可能的清理:

function myFunction(title) {
  var results = [...document.getElementsByClassName("results")]
  results.forEach(function(r) {
    if (title.dataset.for == r.id) {
      r.style.display = "block";
    } else {
      r.style.display = "none";
    }    
  });

  var titles = [...document.getElementsByClassName("title")]
  titles.forEach(function(t) {
    if (t == title) {
      t.style.backgroundColor = "#005FAA"
    } else { 
      t.style.backgroundColor = "lightgrey"
    }
  });
}
body{
margin: 10px;}

.title{
background-color:lightgrey;
width: 32%;
float: left;
text-align: center;
text-decoration:none;
color:white;
margin-right: 2%;
padding: 30px;
box-sizing: border-box;
}


.title:last-child{
margin-right:0px;
width:32%;}

.results{
background-color:#005FAA;
float:left;
width: 100%;
color: white;
padding: 30px;
box-sizing: border-box;
}
<div class="container">
    <div id="title1" data-for="results1" class="title" onclick="myFunction(this)">
        <h4>Item 1</h4>
    </div> 
    <div id="title2" data-for="results2" class="title" onclick="myFunction(this)">
        <h4>Item 2</h4>
    </div> 
    <div id="title3" data-for="results3" class="title" onclick="myFunction(this)">
        <h4>Item 3</h4>
    </div> 
</div>


<div class="results" id="results1" style="display:none;">Item 1</div>
<div class="results" id="results2" style="display:none">Item 2</div>
<div class="results" id="results3" style="display:none">Item 3</div>

我用一个接受表示title元素的参数的函数替换了你的三个函数。在事件处理程序中,我们只是将this传递给该函数。然后在函数中,我们循环遍历可能必须更改的事物(titleresults节点)测试,就像我们正在使用匹配元素或不同的元素并根据它选择行为一样。

要将title元素与results元素链接起来,我会添加一个data-for属性。还有很多其他方法可以做,包括使用正则表达式来查找基本id(例如title2 ~> 2results2 ~> 2)以及匹配。但这应该让你去。

我可能会对此做更多的清理,但这应该提供显着的简化。

更新

评论指出,上述内容不允许取消选择总标签。鉴于此,似乎更好的重构更多并使用共享基本id方法。这是以这种方式编写的另一个版本:

function myFunction(title) {
  var id = title.id.match(/^\D*(\d+)$/)[1]
  var hidden = document.getElementById(`results${id}`).style.display !== 'block';

  [...document.getElementsByClassName("results")].forEach(function(r) {
    r.style.display = "none";    
  });
  [...document.getElementsByClassName("title")].forEach(function(t) {
    t.style.backgroundColor = "lightgrey";
  });

  if (hidden) {
    document.getElementById(`results${id}`).style.display = 'block';
    document.getElementById(`title${id}`).style.backgroundColor = '#005FAA';
  }
}
body{
margin: 10px;}

.title{
background-color:lightgrey;
width: 32%;
float: left;
text-align: center;
text-decoration:none;
color:white;
margin-right: 2%;
padding: 30px;
box-sizing: border-box;
}


.title:last-child{
margin-right:0px;
width:32%;}

.results{
background-color:#005FAA;
float:left;
width: 100%;
color: white;
padding: 30px;
box-sizing: border-box;
}
<div class="container">
    <div id="title1" class="title" onclick="myFunction(this)">
        <h4>Item 1</h4>
    </div> 
    <div id="title2" class="title" onclick="myFunction(this)">
        <h4>Item 2</h4>
    </div> 
    <div id="title3" class="title" onclick="myFunction(this)">
        <h4>Item 3</h4>
    </div> 
</div>


<div class="results" id="results1" style="display:none;">Item 1</div>
<div class="results" id="results2" style="display:none">Item 2</div>
<div class="results" id="results3" style="display:none">Item 3</div>
© www.soinside.com 2019 - 2024. All rights reserved.