0

So I have these DIVs which I have arranged to slide left an right inside of the parent.

See the following JSFiddle to see the design:

http://jsfiddle.net/StevP/C9WL7/

You can see that by adjusting the margin-left of the first child DIV by multiples of -100%, it's rather simple to correctly horizontally position the DIVs inside the parent. Therefore, it's very easy to animate.

Now, this brings me to my issue. I'm using jQuery to move them left and right. It works great. However, I'd like to choose which child the parent gets its height from.

I know, I can just add...

    $('#parent').height($('.child:eq()').outerHeight());

...Which is what I have it currently doing. However, the contents of the children are likely to change causing them to resize (by animate) and, therefore, be cut off. So, having a set height isn't a possibility.

I need to use height:auto; on the parent and somehow cause it to ignore the heights of specific children. I can't for the life of me think of a way.

I don't want to use a timer and onresize/.resize() don't seem to work with my Chrome.

Stev
  • 129
  • 7
  • but in between transitions from a smaller to a larger child, the larger child will necessarily overflow the red bordered box. Perhaps it would help to know why it needs to be cut off? – Joseph Marikle May 16 '14 at 22:06
  • It's not an issue if the ones not meaning to be viewed overflow. Think of them like tabs. You click the third tab, it scrolls horizontally to the third child and adjusts the height accordingly. But, while you have the third tab showing, its height could change and therefore the parent has to use height:auto;. This is an example: http://jsfiddle.net/StevP/86MS6/ – Stev May 16 '14 at 22:13
  • You could try and leave only one child in the flow, and position the others absolutely … – CBroe May 16 '14 at 22:30

2 Answers2

0

You could use jQuery to monitor the DOM subtree and adjust the height of your parent div in the callback like this:

$('.content').bind('DOMSubtreeModified', function(e) {
    if (e.target.innerHTML.length > 0) {
        $(".parent").height($(".content").height());
    }
});

Here's a working jsfiddle: http://jsfiddle.net/9386d/

And a question explaining the dom subtree: jQuery watch for domElement changes?

jQuery docs for bind(): http://api.jquery.com/bind/

Community
  • 1
  • 1
jarbaugh
  • 503
  • 5
  • 10
  • Oh, I've used that in the past but read in a Stack question while I was searching that it shouldn't be used because it was "depreciated". Is it still a viable, professional solution? – Stev May 16 '14 at 22:25
  • I was mistaken. Use .on() instead. Here is the updated code embedded in your jsfiddle: http://jsfiddle.net/xr4V5/ – jarbaugh May 16 '14 at 22:28
  • I've added your solution to the JSFiddle in the comments of my original post. It works fantastic, thanks! – Stev May 16 '14 at 22:41
0

Well... To be perfectly honest I'm not really a huge fan of jQuery anymore so I feel bad offering this answer. It just feels so frik'n inefficient, but here is a solution that does three things: 1) it resizes the hight of the container on step and uses a CSS transition attribute for eye candy (works just as well without). 2) it sets the child height of all but the current child to 0 and uses overflow:hidden so they don't affect the flow of the document anymore. 3) it resets these children to automatic height on animation start so they are visible during transition. All I can say is "yuck", but it does work.

CSS

.child{
       ...
       overflow:hidden;
}

jQuery

var animation_prefs = {
    duration: 3000,
    start: function() {
        $('.child').height('auto');
    },
    step: function(now) {
        var current_index = (Math.floor((now + 50) / 100) * -1);
        $('#parent').height($('.child:eq(' + current_index + ')').outerHeight());
        $('#parent').data('current', current_index);
    },
    complete: function() {
        $('#parent').height('auto');
        $('.child:not(:eq('+$('#parent').data('current')+'))').height(0);
    }
}

$('.child:eq(0)').animate(
    {
        marginLeft:'-200%' //~ Move it back 2 children
    },
    animation_prefs
).animate(
    {
        marginLeft:'-100%' //~ Move it back 1 child
    },
    animation_prefs
).animate(
    {
        marginLeft:'-200%' //~ Move it back 2 children again
    },
    animation_prefs
);

Demo

http://jsfiddle.net/Gq4xs/show

Source

http://jsfiddle.net/Gq4xs/

Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129
  • @user3389410 You're welcome. :) just keep in mind it's rough. Be best to be more efficient like with storing `$('#parent')` in a variable rather than having jQuery fetch it every single time. – Joseph Marikle May 16 '14 at 22:43