How would I make my Bootstrap navbar "collapse"? - javascript

I am trying to replicate the scrolling effect from here: http://www.altisliferpg.com/
I have a feeling that they are using a heavily modified version of Bootstrap Navbar, which I have taken from here: http://www.enjin.com/forums/page/1/m/10826/viewthread/8514993-boot-strap-30-navbar-full-module and have changed it to fit into my specific case.
How would I make it so when you scroll down the page, the bar on the top gets "smaller" and scrolls along with the page as you scroll? Thanks

You can use css transitions for the height, font size and whatever else you want changed. Then simply set a scroll listener, which adds a class to the header so the size changes. Quick (and very ugly) example. jsFiddle
$(window).scroll(function () {
if ($(this).scrollTop()) {
$('#header').addClass('small');
}
else {
$('#header').removeClass('small');
}
});

Maybe you should detect the scroll event of the window, after that, set the position of the navbar to fixed and then, perform the animation. Here's an example of the javascript part and a link see it in action:
$(function(){
var performingDownAnimation = false,
performingUpAnimation = false;
var performScroll = function(){
if($("body").scrollTop() > 0) {
if(performingUpAnimation) {
$('#logo').stop();
performingUpAnimation = false;
}
if(!performingDownAnimation){
$('#navbar').addClass('navbar-fixed');
$('#logo').animate({ 'font-size': "12px" }, 1000, function(){
performingDownAnimation = false;
});
performingDownAnimation = true;
}
}else if($("body").scrollTop() == 0){
if(performingDownAnimation) {
$('#logo').stop();
performingDownAnimation = false;
}
if(!performingUpAnimation){
$('#navbar').removeClass('navbar-fixed');
$('#logo').animate({ 'font-size': "48px" }, 1000, function(){
performingUpAnimation = false;
});
performingUpAnimation = true;
}
}
}
$(document).on('scroll', performScroll);
});
On scroll event and position fixed
I edited my response for adding support for the "up" direction too. About using bootstrap for the animation, I have no idea how to do it, and I think it can't be done, because bootstrap is based mainly on applying CSS classes to different elements. CSS classes are discrete, but you are asking for animating something numerical, as the font-size property is. As much, you could create an animation that looks "staggered".

Related

How do I check if an element is higher than itself?

I'm trying to make a collapsible submenu that, when there isn't enough space to fit all items, will throw overflowing items into a Bootstrap-style dropdown menu.
I'm doing this by checking if the submenu is greater than a certain height. If it's higher than this set height, it's considered overflowing and thus need to run it's function. However, the project I'm working on can't really have set heights on elements. These might change over time, and it will be a maintenance nightmare to go through all the code if something changes.
So how do I check if an element's height is higher than its own (I guess 'initial') height?
Setting if(menuHeight >= menuHeight) will cause a Maximum call stack size exceeded-error and crash the tab in Chrome.
Example:
var CollapseMenu = {
init: function(parent) {
var menu = parent;
var menuHeight = menu.height(); // Using jQuery here; vanilla JS could also work
if(menuHeight >= 64) // This is the set height I want to avoid
// ...
} else {
// ...
}
}
}
$(function() {
var submenu = $('.submenu');
if(submenu.length) {
CollapseMenu.init($('.submenu ul'));
}
$(window).resize(function() {
if(submenu.length) {
CollapseMenu.init($('.submenu ul'));
}
});
});

Detecting the end of a overflow-x:scroll element and add a class before animation

As the title suggests I want to detect the start and end of a scrollable element built using overflow.
The following code works:
var scrollAmount = 150;
var scrollBox = $('.js-compare_scroll');
var arrowLeft = $('.js-compare_scroll_left');
var arrowRight = $('.js-compare_scroll_right');
var inactive = 'm-inactive';
$(arrowLeft).on('click', function () {
$(this).parent().find(scrollBox).stop().animate({
scrollLeft: '-='+scrollAmount
}, function() {
arrowRight.removeClass(inactive);
if(scrollBox.scrollLeft() === 0) {
arrowLeft.addClass(inactive);
}
});
});
$(arrowRight).on('click', function () {
$(this).parent().find(scrollBox).stop().animate({
scrollLeft: '+='+scrollAmount
}, function() {
arrowLeft.removeClass(inactive);
if(scrollBox.scrollLeft() + scrollBox.innerWidth() >= scrollBox[0].scrollWidth) {
arrowRight.addClass(inactive);
}
});
});
However the class to style the inactive colour of the arrows only appears once the animation completes. I need to add the class before the animation completes because it has a delay. I believe by default it is 400.
Is there anyway to detect this and apply the arrow classes where needed?
Thanks.
Came back from a break and realised I should take the checking if its at the end off the click event and onto a scroll event. This works a lot better now.

Smooth jScrollPane scrollbar length adjustment with dynamic content

Some of my webpages contain several text elements that expand and collapse with a jQuery "accordion" effect:
function show_panel(num) {
jQuery('div.panel').hide();
jQuery('#a' + num).slideToggle("slow");
}
function hide_panel(num) {
jQuery('div.panel').show();
jQuery('#a' + num).slideToggle("slow");
}
This causes the window size to change so jScrollPane has to be reinitialized, which will also change the length of the scrollbar. To achieve a smooth length adjustment of the scrollbar, I set the "autoReinitialise" option to "true" and the "autoReinitialiseDelay" to "40" ms:
$(document).ready(function () {
var win = $(window);
// Full body scroll
var isResizing = false;
win.bind(
'resize',
function () {
if (!isResizing) {
isResizing = true;
var container = $('#content');
// Temporarily make the container tiny so it doesn't influence the
// calculation of the size of the document
container.css({
'width': 1,
'height': 1
});
// Now make it the size of the window...
container.css({
'width': win.width(),
'height': win.height()
});
isResizing = false;
container.jScrollPane({
showArrows: false,
autoReinitialise: true,
autoReinitialiseDelay: 40
});
}
}).trigger('resize');
// Workaround for known Opera issue which breaks demo (see
// http://jscrollpane.kelvinluck.com/known_issues.html#opera-scrollbar )
$('body').css('overflow', 'hidden');
// IE calculates the width incorrectly first time round (it
// doesn't count the space used by the native scrollbar) so
// we re-trigger if necessary.
if ($('#content').width() != win.width()) {
win.trigger('resize');
}
});
The effect is ok, but on the cost of a very high CPU usage which makes my fan go wild.
This is a jsfiddle which shows the settings and the effect: http://jsfiddle.net/VVxVz/
Here's an example page (in fact it's an iframe within the webpage shown): http://www.sicily-cottage.net/zagaraenausfluege.htm
Is there a possibility to achieve the same "smooth" transition of the scrollbar length without using the "autoReinitialise" option, maybe with an additional script, some modification of the jscrollpane.js, or simply a css animation of the scrollbar and then calling the reinitialise manually?
I'm absolutely useless at javascript so any help would be greatly appreciated.
There is no need to initialise jScrollPane on your content everytime window is resized. You should do it only once - on $(document).ready(). Also, there is no need in using autoReinitialize if your content is staic. You should reinitialise jScrollPane to update scrollbar size only when you slideUp/slideDown one of your container or on window.resize. So, code become less and more beautiful :)
function togglePanel(num) {
var jsp = $('#content').data('jsp');
jQuery('#a' + num).slideToggle({
"duration": "slow",
"step": function(){
jsp.reinitialise();
}
});
return false;
}
$(document).ready(function () {
var container = $('#content').jScrollPane({
showArrows: false,
autoReinitialise: false
});
var jsp = container.data('jsp');
$(window).on('resize', function(){
jsp.reinitialise();
});
// Workaround for known Opera issue which breaks demo (see
// http://jscrollpane.kelvinluck.com/known_issues.html#opera-scrollbar )
$('body').css('overflow', 'hidden');
// IE calculates the width incorrectly first time round (it
// doesn't count the space used by the native scrollbar) so
// we re-trigger if necessary.
if (container.width() != $(window).width()) {
jsp.reinitialise();
}
});

Slide boxes with margin-left check if overslided

I made a simple content/box slider which uses the following javascript:
$('#left').click(function () {
$('#videos').animate({
marginLeft: '-=800px'
}, 500);
});
$('#right').click(function () {
$('#videos').animate({
marginLeft: '+=800px'
}, 500);
});
Here is the demo: http://jsfiddle.net/tjset/2/
What I want to do and I can't figure out how to show and hide arrows(left and right box) as the all the boxes slided.
So I clicked 4 time to the LEFT and slided all the boxes! then hide "left" so that you can't give more -800px
What can I do?
What you can do is check after the animation completes to see if the margin-left property is smaller or larger than the bounds of the video <div>. If it is, depending on which navigation button was clicked, hide the appropriate navigation link.
Check out the code below:
$('#left').click(function () {
// reset the #right navigation button to show
$('#right').show();
$('#videos').animate({
marginLeft: '-=800px'
}, 500, 'linear', function(){
// grab the margin-left property
var mLeft = parseInt($('#videos').css('marginLeft'));
// store the width of the #video div
// invert the number since the margin left is a negative value
var videoWidth = $('#videos').width() * -1;
// if the left margin that is set is less than the videoWidth var,
// hide the #left navigation. Otherwise, keep it shown
if(mLeft < videoWidth){
$('#left').hide();
} else {
$('#left').show();
}
});
});
// do similar things if the right button is clicked
$('#right').click(function () {
$('#left').show();
$('#videos').animate({
marginLeft: '+=800px'
}, 500, 'linear', function(){
var mRight = parseInt($('#videos').css('marginLeft'));
if(mRight > 100){
$('#right').hide();
} else {
$('#right').show();
}
});
});
Check out the jsfiddle:
http://jsfiddle.net/dnVYW/1/
There are many jQuery plugins for this. First determine how many results there are, then determine how many you want visible, then use another variable to keep track with how many are hidden to the left and how many are hidden to the right. So...
var total = TOTAL_RESULTS;
var leftScrolled = 0;
var rightScrolled = total - 3; // minus 3, since you want 3 displayed at a time.
instead of using marginLeft I would wrap all of these inside of a wrapper and set the positions to absolute. Then animate using "left" property or "right". There's a lot of code required to do this, well not MUCH, but since there are many plugins, I think you'd be better off searching jquery.com for a plugin and look for examples on how to do this. marginLeft is just not the way to go, since it can cause many viewing problems depending on what version of browser you are using.

jQuery Animation Jump

The header to my tumblr page seems a bit jumpy when I attempted to animate its growth and shrinkage when it is no longer on the top of the page.
The webpage is Tobacco Endeavors and is a tumblr blog.
<script type="text/javascript">
$(window).scroll(function(){
if ($(this).scrollTop() > 1) {
$("#abracadabra").fadeOut(500, function(){
$("#header").animate({padding:"1.5em 0"}, 500);
});
} else {
$("#abracadabra").fadeIn(500, function(){
$("#header").animate({padding:"1em 0"}, 500);
});
}
});
</script>
Thanks a bunch guys.
The scroll event could fire many times, you need to control concurrency with a flag, like so:
<script type="text/javascript">
window.flag = true;
$(window).scroll(function(){
if ($(this).scrollTop() > 1) {
if (window.flag) {
window.flag = false;
$("#abracadabra").fadeOut(500, function(){
$("#header").animate({padding:"1.5em 0"}, 500, function() {window.flag = true;});
});
}
} else {
if (window.flag) {
window.flag = false;
$("#abracadabra").fadeIn(500, function(){
$("#header").animate({padding:"1em 0"}, 500, function(){window.flag = true;});
});
}
}
});
</script>
UPDATE:
Updated a typo in code. Try new version above.
stop() and fadeTo() can fix some strange issues sometimes :)
jsBin demo
$(window).scroll(function(){
if ($(this).scrollTop() > 1) {
$("#abracadabra").stop().fadeTo(500,0, function(){
$("#header").stop().animate({padding:"1.5em 0"}, 500);
});
} else {
$("#abracadabra").stop().fadeTo(500,1, function(){
$("#header").stop().animate({padding:"1em 0"}, 500);
});
}
});
about your issue:
from the DOCS:
The .fadeOut() method animates the opacity of the matched elements. Once the opacity reaches 0, the display style property is set to none, so the element no longer affects the layout of the page.
causing jumpy result. On the other hand fadeTo() method
With duration set to 0, this method just changes the opacity CSS property, so .fadeTo(0, opacity) is the same as .css('opacity', opacity).
and as you can see affecting nicely the layout of the page.
See jQuery animate, not smooth
..Just set the easing parameter of the animation to linear.
There are also plugins people have made as alternatives if you feel inclined.
jQuery/JavaScript animations can be jumpy at times, and can also depend on an individuals personal hardware setup. What I like to do for animations is make a css class that has a transition, and the add the class. Additionally, make another css class that has the opposite transition, and add that one to animate out. This works pretty well, and if i'm not mistaken, provides increased browser compatibility.

Categories

Resources