gareth

replacing jquery slideToggle

Recommended Posts

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?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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. 

Share this post


Link to post
Share on other sites

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

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

});

Share this post


Link to post
Share on other sites

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. 

Share this post


Link to post
Share on other sites

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')

});

Share this post


Link to post
Share on other sites

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 1

Share this post


Link to post
Share on other sites

Hi APinix.

 

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

  • Like 1

Share this post


Link to post
Share on other sites

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();
      }
    }
  };
})

Share this post


Link to post
Share on other sites

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()

Share this post


Link to post
Share on other sites

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 1

Share this post


Link to post
Share on other sites

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.