Jump to content
Search Community

replacing jquery slideToggle

gareth
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Posted

Hi,

 

I would like to replace jquery slideToggle with Tweenmax

 

Jquery:

 

$('.acordParent').click(function (e) {
        $(this).next('ul').slideToggle()
         e.preventDefault()
});

 

Tweenmax:
 

 

 $('.acordParent').click(function (e) {
         if (isOpen==false) {
         TweenMax.to($(this).next('ul'), 1, {height:auto})
         isOpen=true
         }else{
         TweenMax.to($(this).next('ul'), 1, {height:0});
         isOpen=false
         }
         e.preventDefault()
        });
 

 

 

but this does not work, I guess there is no such thing as height:auto?

Posted

I'm pretty sure you are going to need to record the "natural" height of each element prior to closing it. I imagine this is what jQuery is doing behind the scenes with slideToggle().

 

I'm no jQuery master, but you can have each ul save its natural height in its own data() object.

 

someULelement.data("height", someULelment.height());

 

Here is an example of a single element that toggles its height on click

See the Pen f787bf03e2008cf253e8fae10d24b354 by GreenSock (@GreenSock) on CodePen.

 

Another approach would be to make use of the fact that a from() tween will automatically record the current height (or any property) that is being tweened.

 

So you could pre-build tweens for all your ul that tween their height from height:0 and then store references to those tweens in each ul's data(). On click you then just need to tell an existing tween to play() or reverse(). 

 

Check it here: 

See the Pen 467080470c0b63716d9991d9fc31ef23 by GreenSock (@GreenSock) on CodePen.

 

Keep in mind, both examples are very simplistic. I'm sure there is a clever way to loop through each element and give it the necessary data, whether its a height value or reference to a tween.

Posted

thanks for this, unfortunately I can't translate your examples into something that works for an accordion menu. I have multiple sub menus, so I can't see how I can record and store their heights.  

 

I will keep trying and will post back if I can come up with something. 

jamiejefferson
Posted

$('.menu').each(function() {

$(this).data('originalheight', $(this).height());

});

Posted

thanks Jamie, the problem I have is I need to use display:none to hide the subs on page load, which cause the height to return as 0. 

jamiejefferson
Posted

Temporarily turn display back on and height should calculate ok


$('.menu').each(function() {

$(this).css('display', 'block')

.data('originalheight', $(this).height())

.css('display', ''); // or css('display', 'none')

});

  • 9 months later...
Posted

Hello gareth,

 

Here's another way of doing it without having to call variables ;)

 

See the Pen CubGg by aPinix (@aPinix) on CodePen.

 

Take a look ;) Hope it helps

  • Like 2
Posted

Hi APinix.

 

Welcome to the GreenSock forums. Thanks so much for providing that codepen example. Very cool.

  • Like 1
  • 10 months later...
Posted

Here is an implementation for doing this in angular with ng-animate  (p.s. i love the code viewer on this site, what is it?)

.animation('.animation-slide-toggle', function() {
  return {
    beforeAddClass : function(element, className, done) {
      if(className == 'ng-hide') {
        TweenMax.set(element, {overflow:"hidden"})
        TweenMax.to(element, 1, {height:0, onComplete:done})
      }
      else {
        done();
      }
    },
    removeClass : function(element, className, done) {
      if(className == 'ng-hide') {
      	TweenMax.set(element, {'display':'block'})
      	naturalHeight = element[0].offsetHeight;
      	TweenMax.set(element, {clearProps:"display"})
      	TweenMax.set(element, {height:0, overflow:"hidden"})
	TweenMax.to(element, 1, {height:naturalHeight, onComplete:done})
      }
      else {
        done();
      }
    }
  };
})
Posted

Temporarily turn display back on and height should calculate ok

$('.menu').each(function() {
    $(this).css('display', 'block')
           .data('originalheight', $(this).height())
           .css('display', ''); // or css('display', 'none')
});

 

This reply makes no sense, if you had jQuery at your disposal why would you even need to redefine slideToggle()

Posted

Hi deweydb and welcome to the GreenSock forums,

 

Thanks for sharing your Angular solution.

 

As for your follow-up question... 

It was pretty clear to us the original poster was simply looking for an alternative way to do things and not necessarily to replace jQuery entirely.

Please try to keep the "makes no sense" accusations to a minimum, ok? Sometimes that stuff can be read the wrong way, especially when you are just joining a community.

 

Looking forward having you around

 

Carl

  • Like 2

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...