Changing sidebar height when dynamic content is added - javascript

I have a 'sticky sidebar nav' that is positioned absolutely relative to the #sidebar div, so it follows the page down on the left hand side and is always available. To make this work I had to add a height to the sidebar, so I used some code to find the height of the container dynamically. This is the code i used:
<script type="text/javascript">
function matchColHeights(col1, col2) {
var col1Height = $(col1).height();
var col2Height = $(col2).height();
if (col1Height > col2Height) {
$(col1).height(col2Height);
} else {
$(col1).height(col2Height);
}
}
$(document).ready(function() {
matchColHeights('#sidebar', 'section#main-container');
})
</script>
Currently the #sidebar div sits inside the section called section#maincontainer. A very simplified version of the html is below.
<body>
<header>Header content</header>
<section id="main-container">
<div id="sidebar">
<ul>
This is the floated ul
<ul>
</div>
<div class="content">
This is where the content of the page sits
</div>
<div class="content2">
This is where the content of the page sits (because of the design there are often more than one divs floated right
<div>Within the content divs are potential expanding divs (accordions and tabs that change size)</div>
</div>
</section>
<footer>Footer content</footer>
</body>
So the problem I have is that there is expandable content (tabs and accordions) in the content area, and when the content expands, the jQuery does not update the height of the sidebar to the new height (this new height could be shorter or longer than the original height). I have tried adding the function to my .click() handler of the accordion (haven't yet tried with the tabs) but here is the code that is used to drop my accordion down:
<!--Content Accordion-->
<script type="text/javascript">
$(document).ready(function() {
$('div.content-accordion> div').hide();
$('div.content-accordion> h4').click(function() {
var $nextDiv = $(this).next();
var $visibleSiblings = $nextDiv.siblings('div:visible');
if ($visibleSiblings.length ) {
$visibleSiblings.slideUp('fast', function() {
$nextDiv.slideToggle('fast');
$matchColHeights('#sidebar', 'section#main-container');
});
} else {
$nextDiv.slideToggle('fast');
$matchColHeights('#sidebar', 'section#main-container');
}
});
});
</script>
As you can see I can add the $matchColHeights('#sidebar', 'section#main-container'); function into the click function and it doesn't refresh to the new height still. I have tried a few other possibilities with no luck.

Just to let everyone know i found a solution...Took alot of messing about but code is below.
I essentially on the click had to set sidebar height back to 0, and create a function that finds the new height of the section#main-container, and then applys that as a css height to the sidebar. This changed the height of the sidebar just fine, but then the sticky sidebar wasnt readjusting to the new height, so i just pasted the code that works my sticky sidebar (the code that starts with $("aside") into the function and it refreshes just fine. Thanks to those that helped.
<!--Content Accordian-->
<script type="text/javascript">
$(document).ready(function() {
$('div.content-accordian> div').hide();
$('div.content-accordian> h4').click(function() {
var $nextDiv = $(this).next();
var $visibleSiblings = $nextDiv.siblings('div:visible');
if ($visibleSiblings.length ) {
$visibleSiblings.slideUp('fast', function() {
$nextDiv.slideToggle('fast', function() {
// START CHANGE SIDEBAR HEIGHT
$("#sidebar").css({ height: 0});
newheight = $("section#main-container").height();
$("#sidebar").css({ height: newheight});
$("aside").stickySidebar({
timer: 500
, easing: "easeInOutQuint"
, constrain: true
});
});
// END CHANGE SIDEBAR HEIGHT
});
} else {
$nextDiv.slideToggle('fast', function() {
// START CHANGE SIDEBAR HEIGHT
$("#sidebar").css({ height: 0});
newheight = $("section#main-container").height();
$("#sidebar").css({ height: newheight});
$("aside").stickySidebar({
timer: 500
, easing: "easeInOutQuint"
, constrain: true
});
});
// END CHANGE SIDEBAR HEIGHT
}
});
});
</script>

I believe you could write
if (col1Height !== col2Height) {
$(col1).height(col2Height);
}
instead of
if (col1Height > col2Height) {
$(col1).height(col2Height);
} else {
$(col1).height(col2Height);
}
But that won't solve your problem.
You probably have to fire that matchColHeights() function from inside a callback like this:
if ($visibleSiblings.length ) {
$visibleSiblings.slideUp('fast', function() {
$nextDiv.slideToggle('fast', function() {
$matchColHeights('#sidebar', 'section#main-container');
});
});
} else {
$nextDiv.slideToggle('fast', function() {
$matchColHeights('#sidebar', 'section#main-container');
});
}
Let me know if it worked.

Related

jQuery toggle slide animation down and up

im creating custom toggle animation on the list of bank while onlick it will toggle down and toggle up. However my code is working but it doesn't show up like an animation form. it just close and down directly without sliding slowly. Kindly advise :
I wish to toggle down for 200 height and toggle up for 102 height
jQUERY :
$(document).ready(function(){
$(".moreBankingBtn").click(function(){
$('.bank_listSetUp').toggleClass('bank_listSetTall'); // Will add/remove class on each click
});
});
HTML :
<div name="bankDisplay2" class="bank_list_main">
<ul data-bind="foreach: thirdPayBank" class="bank_list bank_listSetUp">
<li data-bind="attr:{'data-key':key, 'data-code':bankcode}, css: memberModel.netbankCssClass($data), click: $root.netBankSelectBank" data-key="工商银行" data-code="ICBC" class="bank_2"></li>
<li data-bind="attr:{'data-key':key, 'data-code':bankcode}, css: memberModel.netbankCssClass($data), click: $root.netBankSelectBank" data-key="农业银行" data-code="ABC" class="bank_3"></li>
</ul>
</div>
CSS :
.bank_listSetUp {
height: 102px;
}
.bank_listSetTall {
height: 200px;
}
You can use JQuery UI and change your code to something like
$('.bank_listSetUp').toggleClass('bank_listSetTall',500);
Here 500 is the duration of animation.
I would also suggest you to have a look at sideToggle() function http://api.jquery.com/slidetoggle/
i found an solution for this ,
jQUERY :
$(document).ready(function(){
var open = false;
var bankListMain = $("#thirdPayForm .bank_list_main");
var ul = bankListMain.find("ul");
var button = bankListMain.find("span");
button.click(function () {
open = !open;
var height;
if (open) {
height = "200px";
button.addClass("bank_hide");
} else {
height = "102px";
button.removeClass("bank_hide");
}
TweenMax.to(ul, 0.5, { css: { height: height } });
});
});
NOTE : add tweenmax.js to make it work
try slideToggle()
$(document).ready(function(){
$(".moreBankingBtn").click(function(){
$('.bank_listSetUp').slideToggle();
});
})
It doesn't look like it's animating because you're not using the jquery animate function or the slide toggle function, although since you want to animate to two different heights you can't really use the slide functions, because I believe that's just to display and hide. Maybe try this:
$(document).ready(function(){
$(".moreBankingBtn").click(function(){
If ($('.bank_list').hasClass('bank_listSetUp')){
$('.bank_list').animate({
height: 200,
}, 'slow').promise().done(function(){
$('.bank_list').removeClass('bank_listSetUp').addClass('bank_listSetTall');
});
}
else {
$('.bank_list').animate({
height: 120,
}, 'slow').promise().done(function(){
$('.bank_list').addClass('bank_listSetUp').removeClass('bank_listSetTall');
}
});
});

Slide left and hide effect using jquery or CSS

I am working on a slide menu,
Please have a look at the demo site:
kotechweb.com/new_focus/
At left side there is a main menu , when toggle , the words right now is squeeze and hide, here is how I implement:
var is_closed = false;
$("#menu_btn").on("click", function () {
if (is_closed) {
$(".nav_bar ul").css("width", "75%");
} else {
$(".nav_bar ul").css("width", "0");
}
is_closed = !is_closed;
});
CSS:
transition: all 1s;
So the logic is using transition to implement the slide animation, however, this approach the text is squeeze when the width is smaller.
How to make the text slide left as well?
You can create a "mask" using
#menu_right{
overflow:hidden;
...
}
and move your menu in this way:
var is_closed = false;
$("#menu_btn").on("click", function () {
if (is_closed) {
$(".nav_bar ul").css("margin-left", "-100%");
} else {
$(".nav_bar ul").css("margin-left", "-0%");
}
is_closed = !is_closed;
});
I think this works like espected
First of all, instead of using CSS transitions use animate in JQuery as it allows for more functionality.
What I actually do for my slide menus is adding overflow-x: hidden to my body tag. I then position the menu outside of the page, so I give it the CSS value of right: 0 to position it just outside the left hand side of the page.
What this allows me to do is that when the user clicks the menu button you can animate the menu to slide out by simply changing the right value, so your final code would look something like this
$("#menu_btn").on("click", function () {
if (is_closed) {
$("#slideoutMenu").animate({right:"[insert width of nav menu]"}, 1000);
} else {
$("#slideoutMenu").animate({right:"0"}, 1000);
}
is_closed = !is_closed;
});
Use just jquery and jquery ui : Here
At the top reference the bellowed code.
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
And at script only add this :
$(".nav_bar ul").toggle( "slide");
Or also can use with customized time delay ms unit.
$( ".nav_bar ul" ).toggle( "slide",2000 );
Maybe you should .hide() the text when the sidebar collapses. Hope this helps.

jQuery scrollTop to top of container div

I am using the excellent accordion menu provided by Ian Flynn of RocketMill: http://www.rocketmill.co.uk/create-accordian-boxes-with-a-rotating-arrow-using-css-jquery
This has worked well for me in the past, but I have a new client that leans towards the verbose. This presents a problem when the user attempts to click on their next desired accordion link. The accordion works correctly, but the hyperbolic amount of content shoots off of the page, presenting an obvious usability issue.
What I want to do is to reconcile the top of the active (just clicked on) "menuTitle" div with the top of its parent, the "content" div.
<div id="content">
<div class="menuTitle">
<strong>Title 1…</strong>
</div>
<div class="menuContent"> <!-- Sliding content box -->
<h5>Sub-title 1</h5>
<p>Content</p>
</div> <!-- End of div class="menuContent" -->
<!-- THE ABOVE SEVEN LINES REPEAT FOR EACH FOLD OF THE ACCORDION -->
</div> <!-- End of div id="content" -->
I have been working on this for about three days and have consulted many, many sites, jQuery guides, and whisky. I am not a jQuery expert. Please help!
Oh… I made a jsFiddle. My first: http://jsfiddle.net/Parapluie/CRXX8/
well, if i understand what you want..
http://jsfiddle.net/CRXX8/4/
$(document).ready(function() {
$('#content .menuTitle').on('click',function() {
$('#content .menuTitle').removeClass('on'); // "closes" the closing menu arrow
$('#content .menuContent').slideUp('normal'); // slide-closes the closing div
if($(this).next().is(':hidden') == true) {
$(this).addClass('on'); // "opens" the opening menu arrow
$(this).next().slideDown('normal',function(){
$('html,body').animate({scrollTop:$(this).prev().offset().top}, {queue: false,duration:250, easing: 'swing'}); // on complete slidedown, scroll the clicked .menuTitle to top of page
});// slide-opens the opening div
}
}); // end of click event
}); // end of ready
UPDATE:
As your called elements are wraped in a div called '#focusWide', you dont have to scrollTop html,body, you have to scrollTop the wraper div '#focusWide' and use position().top istead of offset().top. And i add more '11px' (half of wraper div padding).
$('#focusWide').animate({scrollTop:$(this).prev().position().top + 11 + 'px'}, {queue: false,duration:250, easing: 'swing'});
http://jsfiddle.net/CUu7h/2/
I use the function shown below, which works great in most cases. Just make sure the container/wrapper is scrollable (using overflow-y:auto). See fiddle
function scrollIntoView(oElement, sContainer, fnCallback) {
var oContainer, nContainerTop, nContainerBottom, nElemHeight, nElemTop, nElemBottom;
if (!oElement || oElement.length <= 0) {
return;
}
oContainer = (typeof sContainer == "object" ? sContainer : $(sContainer));
nContainerTop = oContainer.scrollTop();
nContainerBottom = nContainerTop + oContainer.height();
nElemHeight = oElement.height() || 25;
nElemTop = oElement[0].offsetTop - 50;
nElemBottom = nElemTop + nElemHeight + 100;
if ((nElemTop < nContainerTop) || (nElemHeight >= $(sContainer).height())) {
oContainer.animate({ scrollTop: nElemTop }, { duration: "fast", complete: fnCallback });
}
else if (nElemBottom > nContainerBottom) {
oContainer.animate({ scrollTop: (nElemBottom - $(sContainer).height()) }, { duration: "fast", complete: fnCallback });
}
else if (fnCallback) {
fnCallback();
}
}

Check to see if content overflows

I need to know when my content overflows my div. If it does, I'll be placing in a link to open the page in a new window with all of the content.
Cheers,
DalexL
Using jQuery and Marquee Text When Text Overflows:
$('div').each(function(){
var $this = $(this);
if ($this.get(0).scrollHeight > $this.height()) {
$this.after('Read More');
}
});
http://jsfiddle.net/eF7jf/
none jQuery answer:
if( elements.scrollHeight > element.clientHeight )
alert('content-overflow')//not to be confused with stackoverflow
If you create a structure like this:
<div id="outer" style="overflow: auto">
<div id="inner">
content
</div>
</div>
then overflow happens when inner's width or height exceeds that of outer since outer assumes the dimensions of the viewport and inner assumes a minimal width and height necessary to display all of content.
You can mark outer as visibility: hidden to cause it to layout but not display.
If content includes position: fixed content then that portion will not be taken into account (and on CSS 2 will not even be clipped).
this a jquery plugin for fit text to width and height:
(function($) {
$.fn.fitText = function(options) {
options = $.extend({
width: 0,
height: 0
}, options);
$(this).each(function() {
var elem = $(this);
if (options.height > 0) {
while (elem.height() > options.height) {
elem.text(elem.text().substring(0, (elem.text().length - 4)) + 'YourLink');
}
}
if (options.width > 0) {
while (elem.width() > options.width) {
elem.text(elem.text().substring(0, (elem.text().length - 4)) + 'YourLink');
}
}
});
}
})(jQuery);

jQuery Multiple Panel Toggle

I'm working on a portfolio site for an iPhone developer. In this site the iPhone app icons will act as a toggle buttons for panels that describe the application. The panels animate over the main page content. To add to this, if a panel is open and another app icon is clicked the open panels will need to close and the next app will open. Currently the script I have works great for toggling a single panel, see here: http://cncpts.me/dev/
So how can change the current script so it accepts multiple ids or classes, without creating duplicate code?
Here is the jQuery that is driving the functionality for a single toggle action.
$(document).ready(function() {
$("li.panel_button").click(function(){
$("div#panel").animate({
height: "700px"
})
.animate({
height: "600px"
}, "slower");
$("div.panel_button").toggle('zoom'); return false
});
$("div#hide_button").click(function(){
$("div#panel").animate({
height: "0px"
}, "slower"); return false
});
});
Here is the HTML:
<div id="panel">
<div id="panel_contents"></div>
<img src="images/iphone.png" border="0" alt="iPhone Development">
<div class="panel_button" id="hide_button" style="display: none;">
<img src="images/collapse.png" alt="collapse" />
</div>
</div>
give the list items a rel attribute that points to the div you are trying to show/hide.
<li rel='#panel_1' class='panel_button'>
give all the div's a common class such as 'flyaway', do a hide on any div with the same class that is not currently hidden
$('.flyaway').not(':hidden').animate({ height: "0px"}, "slower");
and show the one you want
$("li.panel_button").click(function(){
$($(this).attr('rel')).animate({
height: "700px"
})
.animate({
height: "600px"
}, "slower");
$($(this).attr('rel')+" div.panel_button").toggle('zoom'); return false
});
Here is my solution:
// Plugtrade.com - jQuery Plugin :: Bounce //
// answer for http://stackoverflow.com/questions/5234732/jquery-multiple-panel-toggle
jQuery.fn.bounce = function (el, bounceheight) {
var thisdiv = this;
var owidth = thisdiv.width();
var oheight = thisdiv.height();
var trigger = $(el);
// what we want is to make a parent div and then
// get the child div's dimensions and copy it's position
// display, width and height //
// child then becomes an absolute element nested within the
// parent div.
thisdiv.wrap('<div class="bounceparent"></div>');
// let's make a hidden button
thisdiv.append('<input type=text class="bouncehide" style="display:none" />');
var thishidebtn = thisdiv.last();
var thisparent = thisdiv.parent();
thisparent.width(owidth);
thisparent.height(oheight+bounceheight);
thisparent.css('border', '1px solid #ccc');
thisparent.css('position', thisdiv.css('position'));
thisparent.css('overflow', 'hidden');
thisdiv.css('position', 'relative');
thisdiv.css('top', oheight+bounceheight);
thisdiv.css('height', '0');
var toggle = false;
thishidebtn.click(function() {
if(toggle)
{
toggle = false;
thisdiv.animate({ top: 0, height:oheight+bounceheight }).animate({ top: oheight+bounceheight, height:0 });
}
});
trigger.click(function() {
// some code //
if(!toggle)
{
// show
$('.bouncehide').click();
toggle = true;
thisdiv.animate({ top: 0, height:oheight+bounceheight }).animate({ top: bounceheight, height:oheight });
}
else
{
// hide
toggle = false;
thisdiv.animate({ top: 0, height:oheight+bounceheight }).animate({ top: oheight+bounceheight, height:0 });
}
});
// return original object so it can be chained
return thisdiv;
}; // END -> plugin :: bounce
... and here is how you use it:
$(function(){
$('#boinky').bounce('#toggle', 50);
$('#boinkyb').bounce('#toggleb', 50);
});
jsFiddle example:
http://jsfiddle.net/523NH/14/
hope this helps you.

Categories