jQuery Button Only Works Once - javascript

My goal was to create a simple button which once clicked would hide/show a navigational menu, and change the footer's padding alternatively, I'd have used toggle() if not for the latter condition. How do I make the button serve both purposes, that is first hide the menu and decrease footer padding, and then upon another click show the menu and increase the padding, and so forth, so that upon clicking the button one effect would occur and upon another click the other? Any help, suggestions, or alternatives, will be much appreciated.
function collapseOrCondense(event) {
if ($('#block-panels-mini-footer-nice-menu:visible')) {
$('#footer').css({
'padding-bottom': '2.5%'
});
$('#block-panels-mini-footer-nice-menu').hide();
} else {
$('#footer').css({
'padding-bottom': '5.5%'
});
$('#block-panels-mini-footer-nice-menu').show();
}
};
$('#footer').append('<button type=button class=cbutton>*</button>');
$('#footer .cbutton').css({
'position': 'absolute',
'left': '1%',
'top': '1%',
'width': '2%',
'height': '1.5%'
});
$('#footer .cbutton').on('click', collapseOrCondense);

I have made an example here. http://jsfiddle.net/wdakLfcc/2/
var visible = true;
function collapseOrCondense(event) {
if (visible) {
$('#footer').css({
'padding-bottom': '2.5%'
});
$('#block-panels-mini-footer-nice-menu').hide();
visible = false;
} else {
$('#footer').css({
'padding-bottom': '5.5%'
});
$('#block-panels-mini-footer-nice-menu').show();
visible = true;
}
};
$('#footer').append('<button type=button class=cbutton>*</button>');
$('#footer .cbutton').css({
'position': 'absolute',
'left': '1%',
'top': '1%',
'width': '2%',
'height': '1.5%'
});
$('#footer ').on('click', '.cbutton', collapseOrCondense);
On button click different effect will be played - Collapse Or Condense.

It looks like from my analysis that your conditional is always evaluating to true. I propose you add some other form of indicator to better distinguish the toggle.
I jury rigged a simple implementation: http://plnkr.co/edit/y8BugzI89s0i5kxM95H9?p=preview
function collapseOrCondense(event){
if($('#block-panels-mini-footer-nice-menu').css('display') === 'block'){
$('#footer').css({'padding-bottom':'2.5%'});
$('#block-panels-mini-footer-nice-menu').hide();
}
else{
$('#footer').css({'padding-bottom':'5.5%'});
$('#block-panels-mini-footer-nice-menu').show();
}
}
The aforementioned snippet is one way of handling this case given my demo environment -- I am sure there are many ways but the underlying problem is your condition (at least in my scenario with the data provided) is always evaluating to true.

The problem is in this line you have:
if ($('#block-panels-mini-footer-nice-menu:visible')) {
Because that will return a jQuery object with one or zero elements inside. You could fix that by adding .length. But I think using the is function is more clear.
Here I fixed that, and applied some changes that may help you to do the same in a more concise manner:
function collapseOrCondense(event) {
var menu = $('#block-panels-mini-footer-nice-menu');
$('#footer').css({
'padding-bottom': menu.is(':visible') ? '2.5%' : '5.5%'
});
menu.toggle();
}
$('<button type=button class=cbutton>*</button>').css({
'position': 'absolute',
'left': '1%',
'top': '1%',
'width': '2%',
'height': '1.5%'
}).on('click', collapseOrCondense).appendTo('#footer');
Working fiddle: http://jsfiddle.net/yj5evps2/

Related

loading not showing within the box

I have used jquery and css to show a loader with gray background during an ajax call. The thing is I need the loader and the gray background to be visible only within a box like as shown below with loading text and icon in center
My code is working fine but the loader with gray background is showing for the full page like as shown below.
Can anyone please tell me some solution for this
My code is as given below
JSFiddle
ajaxindicatorstart('loading data.. please wait..');
function ajaxindicatorstop()
{
$('#resultLoading .bg').height('100%');
$('#resultLoading').fadeOut(300);
$('.myBox').css('cursor', 'default');
}
function ajaxindicatorstart(text)
{
if($('.myBox').find('#resultLoading').attr('id') != 'resultLoading'){
$('.myBox').append('<div id="resultLoading" style="display:none"><div><img src="http://w3lessons.info/demo/ajax-indicator/ajax-loader.gif"><div>'+text+'</div></div><div class="bg"></div></div>');
}
$('#resultLoading').css({
'width':'100%',
'height':'100%',
'position':'fixed',
'z-index':'10000000',
'top':'0',
'left':'0',
'right':'0',
'bottom':'0',
'margin':'auto'
});
$('#resultLoading .bg').css({
'background':'#000000',
'opacity':'0.7',
'width':'100%',
'height':'100%',
'position':'absolute',
'top':'0'
});
$('#resultLoading>div:first').css({
'width': '250px',
'height':'75px',
'text-align': 'center',
'position': 'fixed',
'top':'0',
'left':'0',
'right':'0',
'bottom':'0',
'margin':'auto',
'font-size':'16px',
'z-index':'10',
'color':'#ffffff'
});
$('#resultLoading .bg').height('100%');
$('#resultLoading').fadeIn(300);
$('.myBox').css('cursor', 'wait');
}
Your loader has a position of fixed, this takes the position of the viewport rather than the position of your element.
$('#resultLoading>div:first').css({
'width': '250px',
'height':'75px',
'text-align': 'center',
'position': 'absolute',
'top':'0',
'left':'0',
'right':'0',
'bottom':'0',
'margin':'auto',
'font-size':'16px',
'z-index':'10',
'color':'#ffffff'
});
$('#resultLoading').css({
'width':'100%',
'height':'100%',
'position':'absolute',
'z-index':'10000000',
'top':'0',
'left':'0',
'right':'0',
'bottom':'0',
'margin':'auto'
});
Also give your myBox a position of relative.

JS image resize compatible with fullPage.js

I am trying to integrate this code : http://codepen.io/babybackart/pen/GZPjJd on a section of a website using fullpage.js.
This code is based on a previous question brilliantly answered by #Seika85 : Make a .div act like an image.
The aim was to "contain" and resize the image on its container ".plancheBox" without cuting it.
In this example, the cat picture's dimensions are driven by the container using this first javascript code:
var calculateImageDimension = function() {
$('.plancheBox img').each(function() {
var $img = $(this),
$plancheBox = $img.closest('.plancheBox');
$img.css({
'max-height': $plancheBox.height() + 2,
/* (+2px) prevent thin margins due to rendering */
'max-width': $plancheBox.width()
});
$img.closest('.container').css({
'position': 'relative'
});
});
}
calculateImageDimension();
In order to set these dimensions instantaneously (without a page refresh), I am using this second javascript code:
var resizeEnd;
$(window).on('resize', function() {
clearTimeout(resizeEnd);
resizeEnd = setTimeout(function() {
$(window).trigger('resize-end');
}, 200);
});
$(window).on('resize-end', function() {
$('.plancheBox img').css({
'max-height': 'none',
'max-width': 'none'
})
$('.plancheBox .container').css({
'position': ''
});
calculateImageDimension();
});
As you can see in the first example, it works without fullpage.js.
I managed to insert the first JS code in a fullpage.js website : http://codepen.io/babybackart/pen/ONrbEN but I don't really manage to insert the second one.
I'm not actually a JS coder so I wanted to know what I needed to do to insert this code, if it was possible to do this with fullpage.js and if there were any conflict between both codes.
Thank you for your answer !
The second JS code must be inserted in a fullPage event like this:
$(document).ready(function() {
$('#fullpage').fullpage({
//events
afterResize: function(){
$('.plancheBox img').css({
'max-height' : 'none',
'max-width' : 'none'
})
$('.plancheBox .conteneur').css({'position' : ''});
calculateImageDimension();
}
});
});

jQuery do action if bigger than but do it just one time

Sorry, maybe my title doesn't really explain well what my problem is but it's a quite simple thing with some example code I guess. :)
I created some styles for a design (a design with high header which need to be compressed when a user will scroll down the page). To get a small header out of a high header I switch the styles of it by jQuery.
By now, I check out the scroll position and on a 'x' position the style needs to be changed. Al this works but my problem is, it will keep on changing the style because of my if/else statement I used, Kinda normal and logic with this statement, but I would like to know how I just fire this one time instead of every scroll height bigger than..
$(window).scroll(function () {
position = $(window).scrollTop();
if ( position > 267) {
$('#heading').addClass('header-shadow');
$("#heading-top").animate({
'opacity': 0
});
$("#heading").animate({
'height': 75,
});
$("#site-header").animate({
'height': 155,
});
$("#container").animate({
'top': 497,
});
} else {
$('#heading').removeClass('header-shadow');
$("#heading-top").animate({
'opacity': 100
});
$("#heading").animate({
'height': 248,
});
$("#site-header").animate({
'height': 328,
});
$("#container").animate({
'top': 595,
});
}
});
Thanks in advance!
Nick
You can look a simple flag based solution. A flag which could tell the in the previous scroll execution whether the condition was already handled or not
(function () {
var flag = $(window).scrollTop() > 267;
$(window).scroll(function () {
var position = $(window).scrollTop();
if (!flag && position > 267) {
flag = true;
console.log('true')
} else if (flag && position <= 267) {
console.log('else')
flag = false;
}
});
})();
Demo: Fiddle

jQuery - Find CSS bottom of div at start, not during animation on hover

I'm finding the CSS value 'bottom' for each of these divs with the class of 'shelf-info-text'. Each of these divs are inside shelf-item.
The bottom value is automatically calculated using another function. On hover I wish bottom to be changed to 0px by way of animation, and then revert to the original bottom. Bottom will be different for every single div.
I have added a little code to find the bottom, however if you hover again mid-animation this finds the bottom before it has returned back to the original state, therefore breaking the animation.
Please advise where I'm going wrong. Thanks.
var $itemBottom = null;
$('.shelf-item').hover(function() {
$itemBottom = $(this).find('.shelf-info-text').css('bottom');
$(this).find('.shelf-info-text').stop().animate({ 'bottom': '0px'}, 300);
}, function() {
$(this).find('.shelf-info-text').stop().animate({ 'bottom': $itemBottom}, 300);
});
Edit :
After re-reading the question here's a solution that will get the bottom and save it in a data attribute.
// we loop through all the shelf items and set a data attribute to keep track of it.
$('.shelf-item').each(function(){
$item = $(this).find('.shelf-info-text');
$itemBottom = $item.css('bottom');
$item.data('bottom', $itemBottom);
});
$('.shelf-item').hover(function() {
$itemBottom = $(this).find('.shelf-info-text').data('bottom');
$(this).find('.shelf-info-text').stop().animate({ 'bottom': '0px'}, 300);
}, function() {
$(this).find('.shelf-info-text').stop().animate({ 'bottom': $itemBottom}, 300);
});
I'm too late to the party (because I got distracted making this fiddle). My approach is the same as #Patsy's but I avoid the .each() loop to set the data-bottom by simply setting it if it doesn't already exist:
var $el = null;
$('.shelf-item').hover(function() {
$el = $(this).find('.shelf-info-text');
$el.data('bottom',($el.data('bottom') || $el.css('bottom'))).stop().animate({ 'bottom': '0px'}, 300);
}, function() {
$el = $(this).find('.shelf-info-text');
$el.stop().animate({ 'bottom': $el.data('bottom')}, 300);
});
You could store the original bottom value using jQuery.data(). Then your function could check to see if that value had been stored, and never recalculate the bottom (avoiding the mid-animation issue).

Todays Special: How is this done? Is there a jquery plugin or product to do it?

I saw this technique at the bottom of a web page where the TAB stays in place at the bottom of the page and can be opened and closed to display more info. I assume it can be rotated to display a different special for different days. Can you point me to anything like it or explain the technique ? thanks. Here is a sample: http://www.tmdhosting.com/ look at the bottom of the page .
position: fixed is how you manage to keep something at the bottom or top of the page, regardless of scrolling.
This is easily discoverable using firebug's (http://getfirebug.com/) inspect element feature
You can check out my version of this at uxspoke.com
I wrote a jQuery plugin to do it, and calling it is straightforward:
$('#about').pulloutPanel({open:true}).
click(function() { $(this).trigger('toggle'); }) });
I basically instrument the panel to support "open", "close" events, and the implement the appropriate animations around them. The only "hard" part is getting the height right. It also supports "toggle" so you can add a generic click handler to it to open or close it. Finally, it uses opened/closed classes to keep track of its current state. That's it!
The code's pretty coupled to the technologies on the page (Csster) and the design it is in, so I'm not sure it will work for you. You can either use Csster, or just put the CSS rules into your stylesheet and remove them from the code. The important Css attributes are the positioning and bottom.
Here it is:
$.fn.pulloutPanel = function(options) {
var settings = $.extend({}, {
attachTo: 'bottom',
css: {
left: 0,
minHeight: 390,
border: '1px 1px 1px 0 solid #666',
has: [roundedCorners('tr', 10),boxShadow([0,0], 10, phaseToColor('requirements').saturate(-30).darken(50))],
cursor: 'pointer'
}, options);
return $(this).each(function() {
var $this = $(this);
$this.addClass('pullout_panel');
$this.bind('open', function(event) {
$this.animate({bottom: 0}, 'slow', 'easeOutBounce', function() {
$this.removeClass('closed').addClass('opened');
$this.trigger('opened');
});
});
$this.bind('close', function(event) {
var height = $this.innerHeight();
$this.animate({bottom: -height + 50}, 'slow', 'easeOutBounce', function() {
$this.addClass('closed').removeClass('opened');
$this.trigger('closed');
});
});
$this.bind('toggle', function(event) {
$this.trigger($this.hasClass('opened') ? 'close' : 'open');
});
once(function() {
Csster.style({
'.pullout_panel': {
position: 'fixed',
bottom: 0,
has: [settings.css]
}
});
});
$this.trigger(settings.open ? 'open' : 'close');
});
};

Categories