zxynz
zxynz

Reputation: 219

jquery click toggle - Closing one element when another is clicked

I have some code which acts as a toggle to open/close an element. I am trying to figure out how to manipulate this so that when one element is clicked - the active one closes.

I have used animation to make the content appear from the right hand side of the page.

Please take a look at the code, I need to access the open callback but not sure how.

(function($) {
  $.fn.clickToggle = function(func1, func2) {
    var funcs = [func1, func2];
    this.data('toggleclicked', 0);
    this.click(function() {
      var data = $(this).data();
      var tc = data.toggleclicked;
      $.proxy(funcs[tc], this)();
      data.toggleclicked = (tc + 1) % 2;
    });
    return this;
  };
}(jQuery));

// cache sliding obj in a var
var tab1 = $('.tab1');
var tab1content = $('.tab1_results');

var tab2 = $('.tab2');
var tab2content = $('.tab2_results');

tab1.clickToggle(function() {
  tab1.animate({
    'right': '450px'
  });
  tab1content.animate({
    'right': '0'
  });
}, function() {
  tab1.animate({
    'right': '0'
  });
  tab1content.animate({
    'right': '-450px'
  });
});

tab2.clickToggle(function() {
  tab2.animate({
    'right': '450px'
  });
  tab2content.animate({
    'right': '0'
  });
}, function() {
  tab2.animate({
    'right': '0'
  });
  tab2content.animate({
    'right': '-450px'
  });
});
.filter {
  position: fixed;
  right: 0;
  z-index: 99;
  top: 0;
  height: 100%;
}

.tab1_results {
  background: #1cb2e7
}

.tab2_results {
  background: #1cb2e1;
}

.tab1_results,
.tab2_results {
  position: fixed;
  width: 450px;
  right: -450px;
  z-index: 99;
  top: 0;
  height: 100%;
}

a.tab1 {
  background-image: url('http://placehold.it/100x100?text=TAB1');
  top: -1px;
  z-index: 100;
  height: 100px;
  width: 100px;
  position: absolute;
  right: 0;
  background-repeat: no-repeat;
  margin-top: 0px;
}

a.tab2 {
  background-image: url('http://placehold.it/100x100?text=TAB2');
  top: 50%;
  z-index: 100;
  height: 100px;
  width: 100px;
  position: absolute;
  right: 0;
  background-repeat: no-repeat;
  margin-top: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="filter">
  <a class="tab1" href="#"></a>
  <div class="tab1_results">
    tab 1 content
  </div>

  <a class="tab2" href="#"></a>
  <div class="tab2_results">
    tab 2 content
  </div>
</div>

Upvotes: 0

Views: 1061

Answers (2)

Jeremy Thille
Jeremy Thille

Reputation: 26360

Don't use jQuery to animate things. Instead, use jQuery to toggle an "active" class, and use CSS transitions to make the active element slide in and the others out.

CSS3 transitions are hardware-accelerated, and overall, that's way less code.

See in Codepen

$(".header").click(function() {
  $(this)
    .parent()
    .toggleClass("active")
    .siblings()
    .removeClass("active")
})
.filter {
  position: absolute;
  right: 0;
  height: 100%;
}

.filter .tab {
  height: 100%;
  width: 200px;
  background: #add8e6;
  border: #808080 solid 1px;
  transition: all 0.3s ease-out;
  z-index: 1;
  position: absolute;
  top: 0;
  left: 0;
}

.filter .tab:nth-child(2) .header {
  top: 110px;
}

.filter .tab:nth-child(3) .header {
  top: 220px;
}

.filter .tab.active {
  transform: translateX(-100%);
  z-index: 2;
}

.filter .tab .header {
  cursor: pointer;
  position: absolute;
  left: 0;
  top: 0;
  background: #d3d3d3;
  color: #a9a9a9;
  width: 100px;
  height: 100px;
  transform: translateX(-100%);
}

.filter .tab .header:hover {
  outline: #a9a9a9 solid 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="filter">

  <div class="tab">
    <div class="header">Tab 1</div>
    <div class="contnet">
      tab 1 content
    </div>
  </div>

  <div class="tab">
    <div class="header">Tab 2</div>
    <div class="contnet">
      tab 2 content
    </div>
  </div>

  <div class="tab">
    <div class="header">Tab 3</div>
    <div class="contnet">
      tab 3 content
    </div>
  </div>
</div>

Upvotes: 2

You could do something like this:

if (tab2.css("right").replace("px","") > 0) {
  tab2.trigger("click");
}

demo

(function($) {
  $.fn.clickToggle = function(func1, func2) {
    var funcs = [func1, func2];
    this.data('toggleclicked', 0);
    this.click(function() {
      var data = $(this).data();
      var tc = data.toggleclicked;
      $.proxy(funcs[tc], this)();
      data.toggleclicked = (tc + 1) % 2;
    });
    return this;
  };
}(jQuery));

// cache sliding obj in a var
var tab1 = $('.tab1');
var tab1content = $('.tab1_results');

var tab2 = $('.tab2');
var tab2content = $('.tab2_results');

tab1.clickToggle(function() {
  if (tab2.css("right").replace("px","") > 0) {
    tab2.trigger("click");
  }
  tab1.animate({
    'right': '450px'
  });
  tab1content.animate({
    'right': '0'
  });
}, function() {
  tab1.animate({
    'right': '0'
  });
  tab1content.animate({
    'right': '-450px'
  });
});

tab2.clickToggle(function() {
  if (tab1.css("right").replace("px","") > 0) {
    tab1.trigger("click");
  }

  tab2.animate({
    'right': '450px'
  });
  tab2content.animate({
    'right': '0'
  });
}, function() {
  tab2.animate({
    'right': '0'
  });
  tab2content.animate({
    'right': '-450px'
  });
});
.filter {
  position: fixed;
  right: 0;
  z-index: 99;
  top: 0;
  height: 100%;
}

.tab1_results {
  background: #1cb2e7
}

.tab2_results {
  background: #1cb2e1;
}

.tab1_results,
.tab2_results {
  position: fixed;
  width: 450px;
  right: -450px;
  z-index: 99;
  top: 0;
  height: 100%;
}

a.tab1 {
  background-image: url('http://placehold.it/100x100?text=TAB1');
  top: -1px;
  z-index: 100;
  height: 100px;
  width: 100px;
  position: absolute;
  right: 0;
  background-repeat: no-repeat;
  margin-top: 0px;
}

a.tab2 {
  background-image: url('http://placehold.it/100x100?text=TAB2');
  top: 50%;
  z-index: 100;
  height: 100px;
  width: 100px;
  position: absolute;
  right: 0;
  background-repeat: no-repeat;
  margin-top: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="filter">
  <a class="tab1" href="#"></a>
  <div class="tab1_results">
    tab 1 content
  </div>

  <a class="tab2" href="#"></a>
  <div class="tab2_results">
    tab 2 content
  </div>
</div>

Upvotes: 1

Related Questions