4lackof 4lackof - 4 months ago 8
CSS Question

JS/jQuery - If statements without "return"

*this question has been updated.

I have a set of boxes which, when clicked open a div called

#expander
. In my code, after
#expander
is opened, and if another box is clicked, I check if the new box clicked is the same as the last box clicked. If it is the same, I close
#expander
, else I briefly close it and then open it again.

This is demonstrated with the this jsfiddle

Here is the same code, in stackoverflow:



$(document).on('click', '.box', function(e) {
if (!$('#expander').hasClass('active')) {
$('#expander').addClass('active');
$('.basic-info').css('border-left', '1px solid black');
activeBox = $(this).attr('id');
$('#main').text(activeBox);
console.log('activeBox = ' + activeBox);
return;
}

if ($('#expander').hasClass('active')) {
$('#expander').removeClass('active');
$('.basic-info').css('border-left', '0px solid black');
if ($(this).attr('id') !== activeBox) {
setTimeout(function() {
$('#expander').addClass('active');
}, 256);
}
activeBox = $(this).attr('id');
$('#main').text(activeBox);
console.log('activeBox = ' + activeBox);
return;
}
});

#expander{
height: 100%;
width: 0%;
float: left;
visibility: hidden;
overflow: hidden;
background-color: grey;
transition: .75s ease-out;
}
#expander.active{
height: 100%;
width: 50%;
z-index: 1;
visibility: visible;
}
#closer{
padding: 4px;
margin: 0px;
background-color: #707070;
color: white;
font-size: 1.5em;
text-align: center;
cursor: pointer;
}
#closer:hover{
background-color: #606060;
font-size: 2em;
padding: 0px;
}
.box{
width: 32px;
height: 32px;
padding: 5px 0px;
margin: 0px 4px;
display: inline-block;
background-color: grey;
overflow: hidden;
font-size: 1em;
font-weight: bold;
text-align: center;
border: 1px solid transparent;
border-radius: 2px;
cursor: pointer;
}
.basic-info{
padding: 8px 16px;
color: white;
background-color: #47a;
border-top: 1px solid black;
border-right: 1px solid black;
border-bottom: 1px solid black;
transition: .5s ease-out;
cursor: pointer;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="expander">
<div id="closer" title="Close"><span>&times</span></div>
<div id="main"></div>
</div>
<div class="basic-info">
<div id="box1" class="box">1</div>
<div id="box2" class="box">2</div>
<div id="box3" class="box">3</div>
</div>





The above code works (although it does not look exactly how it looks in my final layout) BUT what it does not do run this:
$('.basic-info').css('border-left', '1px solid black');
after the first time a box is clicked (when it opens the
#expander


I realize the reason this is not working is that the JS code first adds the classes and styles, but then the next if statement removes the classes and styles. Also, I have to paste the following code two times:

$('#main').text(activeBox);
console.log('activeBox = ' + activeBox);
return;


Does anyone know a better way to layout my if statements so that code does not conflict? Also, is there a way to not need to use
return;
s?


P.S. does anyone have a link to a good
if statement
tricks tutorial so that I can learn these things for the future?

Thank you.




UPDATE:

I have updated the code based on the current answers and have changed the JS to this:

$(document).on('click', '.box', function(e) {
if ($('#expander').hasClass('active')) {
$('#expander').removeClass('active');
if ($(this).attr('id') !== activeBox) {
setTimeout(function() {
$('#expander').addClass('active');
}, 256);
activeBox = $(this).attr('id');
console.log('activeBox = ' + activeBox);
return;
}
$('.basic-info').css('border-left', '0px solid white');
return;
}
$('#expander').addClass('active');
$('.basic-info').css('border-left', '1px solid white');
activeBox = $(this).attr('id');
console.log('activeBox = ' + activeBox);
}


(it does the same thing, just laid out differently). All I am trying to figure out now is just how I can write this without any of the
return;
s and also so I do not have to write
activeBox = $(this).attr('id'); console.log('activeBox = ' + activeBox);
twice (unless these things are impossible/unavoidable)


thank you.

Answer

for the clean up part and get rid of repeated data, you can convert your js code to this

Updated

jsFiddle

// target the #expander 
var Expander = $('#expander'),
  activeBox = '';

$(document).on('click', '.box', function(e) {
  //toggleClass means if #expander hasClass, remove it, if it
  //doesn't have the class, add it.
  Expander.toggleClass('active');
  // same for .basic info, we use toggle class, instead of
  // CSS hardcoded, thus we can toggle
  $('.basic-info').toggleClass('black-border-left');

  if ($(this).attr('id') !== activeBox) {
    Expander.removeClass('active');
    // to get rid of the delay for when one .box div is clicked for the first time
    // when activeBox = ''.
    if(activeBox !== ''){
      setTimeout(function() {
        Expander.addClass('active');
      }, 500);
    }else{
      Expander.addClass('active');
    }
    activeBox = $(this).attr('id');
  }
  $('#main').text(activeBox);
  console.log('activeBox = ' + activeBox);
});