Javascript нуждается в упрощении - складные вкладки - PullRequest
0 голосов
/ 06 апреля 2019

Я закодировал некоторые вкладки, и они, кажется, работают хорошо, хотя я уверен, что смогу добиться этого с помощью намного более чистого кода! Я просто не уверен, как это сделать в данный момент. Я был бы очень признателен за помощь с этим.

Я не уверен, что его циклы я хочу использовать или что-то совершенно другое?

То, как я это сделал, очевидно работает, но это просто кажется ненужным и грязным, после этого следующим шагом будет добавление эффекта перехода по мере нажатия вкладок. Я не уверен, позволит ли это мне это сделать.

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>

Ответы [ 3 ]

0 голосов
/ 07 апреля 2019

Может как то так?Вы уже используете 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 голосов
/ 07 апреля 2019

Попробуйте, вы можете вызвать одну и ту же функцию на всех трех элементах div, передав их идентификаторы, чтобы найти текущий идентификатор.

<!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 голосов
/ 06 апреля 2019

Вот одна из возможных очисток:

* *

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"
    }
  });
}
1004
<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>
1006 1008

Я заменил свои три функции с одной функцией, которая принимает параметр, представляющий элемент заголовка.В обработчике событий мы просто передаем this этой функции.Тогда в функции, мы перебираем вещи, которые, возможно, придется изменить (title и results узлы) тестирования, как мы делаем ли мы работаем с элементом согласования или другим и выбирают поведение на основе этого.

1014 * для того, чтобы связать title элементы с results один, я добавляю data-for к нему атрибут.Есть много других способов, это может быть сделано, в том числе с использованием регулярных выражений, чтобы найти базовый идентификатор (title2 ~> 2 results2 ~> 2, например) и соответствия на них.Но это должно заставить вас идти. 1021 * Существует более очистки, я бы, вероятно, сделать на этом, но это должно предложить значительное упрощение. 1023 * Update 1025 * Комментарий указал, что выше не позволяет общей закладке отмене выбора.Учитывая это, кажется, лучше реорганизовать немного больше и использовать подход с идентификатором общей базы.Вот еще одна версия, написанная таким образом:

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>
...