SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    328
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    How to $('#DIV name').height(); with an accordion on page?

    Hi all,

    I'm in a spot of bother with the below.

    I'm trying to calculate the height of a DIV containing an accordion which dynamically grows and shrinks when the accordion is clicked.

    If it wasn't for the accordion things would be easy. With the accordion I can't calculate the current height of the accordion's DIV without reloading the page. Reloading the page isn't an option with accordions so it's a catch 22.

    Consequently, the below code is fine for traditional websites.

    My query is how can I somehow insert a background timer (or whatever) to do this without the page having to be reloaded? If page reloading was even an option then it would still only always return the height of the accordion DIV with the first accordion bar clicked (with short content as it happens).

    <script type="text/javascript">

    $(document).ready(function(){

    var height1 = $('#<DIV containing accordion, dynamically grows/shrinks when accordion is clicked and displays varying length content>').height();

    $("#<DIV of the column I want to dynamically increase its height inline with the height of the DIV containing the accordion").height(height1);

    });

    </script>


    Many thanks,

  2. #2
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    328
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Okay. I think to be getting somewhere. Basically I've done testing and I think the optimum way to do it would be to just append the necessary code to the accordion script so it resets the DIV height (the one I want it to change) to the right value.

    So far it's working but errenously. It keeps getting the wrong height from the DIV containing the accordion thus setting the other DIV height up incorrectly.

    The code controlling the accordion is as follows:

    $(document).ready(function(){

    //Set default open/close settings
    $('.accordion_container').hide(); //Hide/close all containers
    $('.accordion_trigger:first').addClass('active').next().show(); //Add "active" class to first trigger, then show/open the immediate next container

    //On Click
    $('.accordion_trigger').click(function(){
    if( $(this).next().is(':hidden') ) { //If immediate next container is closed...
    $('.accordion_trigger').removeClass('active').next().slideUp(); //Remove all .acc_trigger classes and slide up the immediate next container
    $(this).toggleClass('active').next().slideDown(); //Add .acc_trigger class to clicked trigger and slide down the immediate next container

    $(document).ready(function(){

    var height1 = $("#annoucement-area-880").height();

    $(".content-annoucement-243").height(height1 - 40);
    $("#annoucement-area-243").height(height1);
    });


    }

    return false; //Prevent the browser jump to the link anchor
    });

    });


    The code in bold is what I've added.

    #annoucement-area-880 is the DIV housing the accordion (see below for structure).

    .content-annoucement-243 is the content class inside of the DIV I want to adjust.

    Just so you know the page in question doesn't use columns but has a lego brick type structure. I call them announcements. They vary in width and can be mixed and matched on page so suit the content type. Here's an example of how each "annoucement" is setup, this one is 880px wide:

    <!-- Start of Annoucement -->
    <div id="annoucement-area-880">
    <div class="content-annoucement-top-880"></div>
    <div class="content-annoucement-880">
    <?php include($doc_root.'/path to content/file.php'); ?>
    </div>
    <div class="content-annoucement-bottom-880"></div>
    </div>
    <!-- End of Annoucement -->

    Hopefully you can give me some pointers? It's almost as if the code setting up the new height is getting confused with previous height values as sometimes it ads on too much height, at other times too little. So far I can't see a pattern forming to figure out what's going on.

    Thanks,

  3. #3
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    328
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just to give you a further insight. This is how the accordion is structured. There's four accordion bars that make up the entire accordion. From the below in theory at least the class .container should hold the accordion height. While it does hold a value it seems totally unrelated to the real accordion height.

    <div class="container">

    <h2 class="accordion_trigger"><a href="#">Product type 1</a></h2>
    <div class="accordion_container">
    <h2><img class="middle" style="margin-right: 3px;" src="/images/buy_selected.png" width="48" height="48" alt="buy product" />Select product type 1</h2>
    <div class="accordion_content_container">

    <!-- Add content -->
    <?php include($_SERVER['DOCUMENT_ROOT'].'/path to products/products.php'); ?>
    <!-- End Add content -->

    </div>
    </div>

    <h2 class="accordion_trigger"><a href="#">Product type 2</a></h2>
    <div class="accordion_container">
    <h2><img class="middle" style="margin-right: 3px;" src="/images/buy_selected.png" width="48" height="48" alt="buy product" />Select product type 2</h2>
    <div class="accordion_content_container">

    <!-- Add content -->
    <?php include($_SERVER['DOCUMENT_ROOT'].'/path to products/products.php'); ?>
    <!-- End Add content -->

    </div>
    </div>

    <h2 class="accordion_trigger"><a href="#">Product type 3</a></h2>
    <div class="accordion_container">
    <h2><img class="middle" style="margin-right: 3px;" src="/images/buy_selected.png" width="48" height="48" alt="buy product" />Select product type 3</h2>
    <div class="accordion_content_container">

    <!-- Add content -->
    <?php include($_SERVER['DOCUMENT_ROOT'].'/path to products/products.php'); ?>
    <!-- End Add content -->

    </div>
    </div>

    <h2 class="accordion_trigger"><a href="#">Product type 4</a></h2>
    <div class="accordion_container">
    <h2><img class="middle" style="margin-right: 3px;" src="/images/buy_selected.png" width="48" height="48" alt="buy product" />Select product type 4</h2>
    <div class="accordion_content_container">

    <!-- Add content -->
    <?php include($_SERVER['DOCUMENT_ROOT'].'/path to products/products.php'); ?>
    <!-- End Add content -->

    </div>
    </div>

    </div>

    Thanks again.

  4. #4
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    328
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just to add the latest status. I've changed the background color of <div class="container"> to black just to double check its height increases and it works perfectly. The exact same is also true for <div class ="content-annoucement-880">, both are excellent candidates for getting the height value from.

    Why on earth it goes haywire somewhere from getting this height programatically (during runtime) from either DIV to setting this heigh to the other DIV is really beyond me.

  5. #5
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    328
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think I know what's going wrong but not sure in as far as a solution to fix it.

    I *think* what's happening is that each time the below accordion code is executed, height1 is reported as the *previous* height of .content-annoucement-880 and not the *new* height after the accordion has resized itself. As a result the other DIV's height (the one I wish to control) gets set a wrong height.

    Anyone concurs? Disagrees? Maybe has any other suggestions?


    $(document).ready(function(){

    //Set default open/close settings
    $('.accordion_container').hide(); //Hide/close all containers
    $('.accordion_trigger:first').addClass('active').next().show(); //Add "active" class to first trigger, then show/open the immediate next container

    //On Click
    $('.accordion_trigger').click(function(){
    if( $(this).next().is(':hidden') ) { //If immediate next container is closed...
    $('.accordion_trigger').removeClass('active').next().slideUp(); //Remove all .acc_trigger classes and slide up the immediate next container
    $(this).toggleClass('active').next().slideDown(); //Add .acc_trigger class to clicked trigger and slide down the immediate next container

    $(document).ready(function(){

    var height1 = $(".content-annoucement-880").height();

    alert(height1);


    $("#annoucement-area-243").height(height1);
    $(".content-annoucement-243").height(height1 - 40);
    });

    }

    return false; //Prevent the browser jump to the link anchor
    });

    });

  6. #6
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    328
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If anyone is still reading this...

    I have done enough testing to be 95&#37; sure that it's simply a case of the wrong value of height being passed to the 2nd DIV. For some reason calling the inbuilt .height(); jquery function inside the accordion code (which gets activated each time the accordion is clicked) yields a bogus height. Passing (setting) a bogus height to a different DIV will never get both DIV's to have the same height. Ahhh the joy hey...

    It would seem that:
    1) something is interfering with the .height(); code inside the accordion function
    2) .height(); just doesn't play ball with dynamically resized DIV's hence why it's just not going to cooperate with the accordion's DIV
    3) .height(); works fine but it needs to be called from somewhere else away from code that may interfere. Where and how is so far a mystery.

    As of yet this issue isn't solved

  7. #7
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    328
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've done a test whereby I get the DIV height from a DIV that's height is static (i.e. one that doesn't contain an accordion or any other dynamic code).

    The result is as expected, it works fine always setting the correct DIV height on each click on the accordion.

    This just underlines that for some reason I can't get the true height of the DIV containing the accordion. Could it be that jquery polls the .height() before the accordion finishes resizing the DIV it's nested in? Some kind of synchronization issue.

    Anyway, the below code works fine so long as the source DIV height isn't the one containing an accordion.

    $(document).ready(function(){

    //Set default open/close settings
    $('.accordion_container').hide(); //Hide/close all containers
    $('.accordion_trigger:first').addClass('active').next().show(); //Add "active" class to first trigger, then show/open the immediate next container

    //On Click
    $('.accordion_trigger').click(function(){
    if( $(this).next().is(':hidden') ) { //If immediate next container is closed...
    $('.accordion_trigger').removeClass('active').next().slideUp(); //Remove all .acc_trigger classes and slide up the immediate next container
    $(this).toggleClass('active').next().slideDown(); //Add .acc_trigger class to clicked trigger and slide down the immediate next container

    resize();

    }
    return false; //Prevent the browser jump to the link anchor
    });


    function resize() {

    $(document).ready(function(){

    $("#annoucement-area-243").height($("#annoucement-area-880").height());
    $(".content-annoucement-243").height($(".content-annoucement-880").height());

    });

    }

    });

  8. #8
    SitePoint Member
    Join Date
    Mar 2011
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I am having the same issue as you although I am having a hard time connecting the dots between your posts. I have attached an image that shows the structure of what I'm trying to do which I assume is the same. I have a fullbox that contains a photobox and accordbox. I want the photobox to increase when the accordion is clicked as well as in the beginning of the page. I ran into the same issue issuing that adjust height function up top where it only wanted to take in account the previous accordion length making it screwy. If I understand correctly you use function resize() {

    $(document).ready(function(){

    $("#annoucement-area-243").height($("#annoucement-area-880").height());
    $(".content-annoucement-243").height($(".content-annoucement-880").height());

    });
    to do the work for you. In my example in which I attached a gif to show the structure just so you're not confused it would be

    $(".photobox").height($(".fullbox").height());
    $(".accordbox").height($".fullbox").height());

    I'm a bit confused on what heights your checking with what to make the adjusting hieght in your examples please explain for I have spent my saturday on it lol
    Attached Images Attached Images

  9. #9
    SitePoint Addict
    Join Date
    Nov 2009
    Posts
    328
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry for the late reply.

    Yes, what you're doing is similar to mine except I have more div's on the page that represent "panels" with content and you want to resize a div on the left rather than on the right side. Beyond that it seems similar.

    First of all I think your problem rests in the order in which your code runs. Here's the accordion code below, the _index in the name is just to mean that accordion is on the index page (since I have more elsewhere through the side and I like easy names etc.).

    Code JavaScript:
    $('.accordion_trigger_index').click(function(){
    	if( $(this).next().is(':hidden') ) { //If immediate next container is closed...
    		$('.accordion_trigger_index').removeClass('active').next().slideUp();
    		$(this).toggleClass('active').next().slideDown(function() {		
     
    			//scroll to top of id7 div accordion trigger (first from top)
    			goToByScroll('h2.accordion_trigger_index');			
     
    		}); 	
     
    	}
    	return false; //prevent the browser jump to the link anchor
    });

    Notice that I am first sliding down the next container after the trigger and only once that is done am I calling a function that resizes the div I want, in this case it's one 243px wide hence the name. The next container in the accordion just for checks is the one that holds your content.

    After that we go onto the resize code which looks like this:

    Code JavaScript:
    function resize_announcement_243_div() {
     
    	//Resizes div id8 height so it aligns with div id9
     
    	$(document).ready(function(){
     
    			//get top position announcement div id7
    			var top_div = $( ".annoucement-top-880.id7" );	
    			var top_div_offset = top_div.offset();	
    			var top = top_div_offset.top;
     
    			//get bottom most position of annoucement div id9	
    			var bottom_div = $( ".annoucement-bottom-880.id9" );			
    			var bottom_div_offset =  bottom_div.offset();	
    			var bottom = (bottom_div_offset.top + bottom_div.height());
     
    			//calculate how tall the announcement div should be		
    			var height = (bottom - top);			
     
    			//announcement div id8 has additional top padding to take into account when calculating its height
    			height = height - 20;			
     
    			//resize announcement div id8 content area
    			var div = $( ".annoucement-content-243.id8" );
    			var startHeight = div.height();			
    			var endHeight = height; 
    			div.height( startHeight ).animate({ height: (endHeight - (top_div.height() + bottom_div.height()) )});				
     
    	});

    Each of my "panels" I call announcements and each is made up of three divs, a top div, a content div and a bottom div. This is just so I can style them.

    Notice I am getting the top y position of the top most part of the top div and then getting the same top position of the bottom div but also taking into account its height since I need the far most down y position.

    Once I have this I know I can calculate how tall the page has grown and animate the div I want to animate (that's beside the accordion) to the new height. The padding - 20 is just there since I have a top-padding: 20px in that div so content doesn't appear too near the top.

    From what I can see you don't want to be getting the new height of your accordion but rather the div in which it's contained (the parent div). If you have it setup like me (top div, content div, bottom div) then the content div will resize automatically. Use this to your benefit (work with the flow so to speak).

    goToByScroll() is just a function call I have to change the viewport once the accordion performs its resize, this is because some content is rather long and if a user clicks a lower accordion trigger it's somewhat annoying to have to manually scroll up the page. I do this automatically to improve the overall user experience.

    That should help you.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •