JQuery .css() function doesn't change all properties - javascript

I'm creating a UI with sliding panels much in the fashion of this site: http://smithandhawken.catalogs.target.com/#/intro-cover
I have two ways to change the pages though, by column and by row. The user can use the keyboard as well as some visual elements to navigate the pages. The movement is handled by functions like this:
function moveDown()
{
unbindAll();
currentPage = 1;
$('div.section').each(function(index, element) {
if(index+1 == currentSec) {
console.log($(this));
$(this).css({ 'margin-top': 0, 'z-index': (storyCount-1)*100 });
if($(this).next().size()) {
populate(currentSec+1, currentPage);
$(this).next().children('div.page').css('left', $(window).width());
$(this).next().children('div.page').eq(0).css('left', 0);
console.log(storyCount);
$(this).next().css({ 'margin-top': $(window).height(), 'z-index': storyCount*100 }).stop().animate({marginTop:0}, 500, function() {
currentSec++;
bindAll();
});
}
else {
populate(1, currentPage);
$(this).parent().children().first().children('div.page').css('left', $(window).width());
$(this).parent().children().first().children('div.page').eq(0).css('left', 0);
$(this).parent().children().first().css({ 'margin-top': $(window).height(), 'z-index': storyCount*100 }).stop().animate({marginTop:0}, 500, function() {
currentSec = 1;
bindAll();
});
}
}
else if(index != currentSec) {
$('#section'+(index+1)).css({ 'margin-top': 0, 'z-index': 100 });
}
});
}
THe line above that doesn't work the same way 100% of the time is - $(this).css({ 'margin-top': 0, 'z-index': (storyCount-1)*100 });
When the user uses the keyboard and the left/right visual elements, everything works fine. When they use the visual elements that translate between each row (up/down methods only), the function fires, but not all CSS properties are applied. Here is the function for the visual elements I'm talking about:
function mdlButton(btnHit)
{
btnLabel = btnHit.attr('id').substr(3);
console.log('enter first swtich '+currentSec);
switch(currentSec)
{
case 1:
console.log('enter second switch '+btnLabel);
if (btnLabel == 1) {
console.log('dont do anything');
}
else if (btnLabel == 2) {
console.log('move down one');
moveDown();
}
else if (btnLabel == 3) {
console.log('move down two');
moveDown();
moveDown();
}
break;
case 2:
console.log('enter second switch');
if (btnLabel == 1) {
console.log('move up');
moveUp();
}
else if (btnLabel == 2) {
console.log('dont do anything');
}
else if (btnLabel == 3) {
console.log('move down one');
moveDown();
}
break;
case 3:
console.log('enter second switch');
if (btnLabel == 1) {
console.log('move up two');
moveUp();
moveUp();
}
else if (btnLabel == 2) {
console.log('move up');
moveUp();
}
else if (btnLabel == 3) {
console.log('dont do anything');
}
break;
}
if(!btnHit.hasClass('mdlSelected')) {
$('div.mdlSec').removeClass('mdlSelected');
$('div.mdlSec').find('#selected').remove();
btnHit.addClass('mdlSelected');
btnHit.find('div.divider').after('<div id="selected"></div>');
reSize();
}
}
I can't figure out the reason why the z-index wouldn't change when called from the above function as opposed to just the keyboard or when left/right call the moveDown()/moveUp() methods. Just in case, here's what the left/right look like:
function moveLeft()
{
unbindAll();
$('#section'+currentSec+' div.page').each(function(index, element) {
if(index+1 == currentPage) {
if($(element).prev().size()) {
populate(currentSec, currentPage-1);
$(this).animate({'left': $(window).width()}, 500, function() {
currentPage--;
bindAll();
});
}
else {
moveUp();
}
}
});
}
Any help would be much appreciated! Thanks

The z-index was being reset back to another value by the reSize() function which was called to resize the footer buttons. I've separated the resize functions and the problem disappeared. No problems with the code itself, just the execution order.
Thanks for all the help!

Related

how to make an animation only 1 time on scroll

This is my code: Fiddle
countEach()
$(window).on('scroll', function(e) {
countEach()
})
function countEach() {
$('.count').each(function() {
if (showOnScreen(this) && $(this).attr('show') != 'false') {
console.log($(this).text())
console.log($(this).attr('show'))
$(this).attr('show', 'false')
numberAnimate(this)
} else if (!showOnScreen(this)) {
$(this).attr('show', 'true')
}
})
}
function showOnScreen(target) {
if ($(window).scrollTop() + $(window).height() >= $(target).offset().top)
return true;
else
return false;
}
function numberAnimate(target) {
var $this = $(target);
jQuery({
Counter: 0
}).animate({
Counter: $this.text()
}, {
duration: 1000,
easing: 'swing',
step: function() {
$this.text(this.Counter.toFixed(1));
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="count">5.6</span>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<p>Scroll up and then scroll down again</p>
<span class="count">5.6</span>
The problem is, the increasing number animation will run again, if i scroll up and scroll down again. What is the thing that i need to change to stop it? I tried a lot of things, but i am not good at Javascript.
You need to declare a global var as stopNow = 2 so your animation can only run twice and decrement it when animation runs.
var stopNow = 2;
Update the countEach function as follows
function countEach() {
$('.count').each(function() {
//also check stopNow != 0
if (showOnScreen(this) && $(this).attr('show') != 'false' && stopNow != 0) {
console.log($(this).text())
console.log($(this).attr('show'))
$(this).attr('show', 'false')
numberAnimate(this)
stopNow = stopNow - 1; //decrement stopNow
} else if (!showOnScreen(this)) {
$(this).attr('show', 'true')
}
})
}
Here's your updated working fiddle - https://jsfiddle.net/6w8ubh5y/7/
Use a global variable. Set it to false at the beginning. In the scroll event, check it and if it is still false, run the countEach() function then change the variable to true. Like this:
var stop = false;
countEach();
$(window).on('scroll', function(e) {
if(!stop){
countEach();
stop = true;
}
})
Change the event binding code from:
$(window).on('scroll', function(e) {
countEach()
})
to
$(window).on('scroll', countEach);
and change countEach function like this...
function countEach() {
$('.count').each(function() {
...
});
$(window).off('scroll', countEach); // add this line
}

Jquery - On Scroll change content of a div with animation (waypoint js)

I was trying to make something similar to this site (service section)
I almost achieved the basic functionality by using waypoint.js but unable to make transition animation i.e. controlled with scroll.
I tried doing this jquery fadeout and fadein but that makes sometime if we scroll fast, waypoint event not triggering.
You can view my code (friddle) here
var $fixe = $('.fixe');
var $one = $('.one');
var $two = $('.two');
var $three = $('.three');
var $four = $('.four');
var $end = $('.dummy');
$fixe.waypoint(function (direction) {
if (direction == 'down') {
$fixe.addClass('fixed');
}
else {
$fixe.removeClass('fixed');
}
});
$one.waypoint(function (direction) {
if (direction == 'down') {
$('p').text("This is a test ONE");
$('img').attr("src","https://placeholdit.imgix.net/~text?txtsize=22&txt=Hello+TWO&w=200&h=100&txttrack=0");
}
else {
$('p').text("This is a test ZERO");
$('img').attr("src","https://placeholdit.imgix.net/~text?txtsize=22&txt=Hello+ONE&w=200&h=100&txttrack=0");
}
});
$two.waypoint(function (direction) {
if (direction == 'down') {
$('p').text("This is a test TWO");
$('img').attr("src","https://placeholdit.imgix.net/~text?txtsize=22&txt=Hello+THREE&w=200&h=100&txttrack=0");
}
else {
$('p').text("This is a test ONE");
$('img').attr("src","https://placeholdit.imgix.net/~text?txtsize=22&txt=Hello+TWO&w=200&h=100&txttrack=0");
}
});
$three.waypoint(function (direction) {
if (direction == 'down') {
$('p').text("This is a test THREE");
$('img').attr("src","https://placeholdit.imgix.net/~text?txtsize=22&txt=Hello+FOUR&w=200&h=100&txttrack=0");
}
else {
$('p').text("This is a test TWO");
$('img').attr("src","https://placeholdit.imgix.net/~text?txtsize=22&txt=Hello+THREE&w=200&h=100&txttrack=0");
}
});
$end.waypoint(function (direction) {
if (direction == 'down') {
$fixe.removeClass('fixed');
}
else {
$fixe.addClass('fixed');
}
}, { offset: '99%' });
Also when the last waypoint event triggered the "fixed" class removed which causing big blank space. Is there any way to solve this.

if statement compare places

We are working on another game and we have several answers to a question. Now the problem is that I need to compare the place of the whale to the place of a fish with the answer.
Does anyone know how to do that?
var Keys = {
left: 37,
right: 39,
up:38,
down:40
}
function Start(){
$("#start").hide();
alert ("test start weg");
Opdr1();
}
$(function(){
$(document).keydown(function(e){
switch(e.which){
case Keys.right:
$("#whale").css("left", "+=10px");
$("#whale").attr("src", "pacman-right.png");
break;
case Keys.left:
$("#whale").css("left", "-=10px");
$("#whale").attr("src", "pacman-left.png");
break;
case Keys.up:
$("#whale").css("top", "-=10px");
break;
case Keys.down:
$("#whale").css("top", "+=10px");
break;
}
});
});
function Opdr1(){
$(".bubbel").css("visibility", "visible");
$(".vis1-1").css("visibility", "visible");
$(".vis2-1").css("visibility", "visible");
$(".vis3-1").css("visibility", "visible");
$(".vis4-1").css("visibility", "visible");
//if the whale's css left and top is the same as the left and top of the vis-1 then { }
if($("#whale").css("left") == ("left") {
alert('vis-1 fout');
}
if($("#whale").css('left') == (".vis2-1").css('left')) {
alert('vis-2 fout');
}
if($("#whale").css('left') == (".vis3-1").css('left')) {
alert('vis-3 fout');
}
if($("#whale").css('left') == (".vis4-1").css('left')) {
alert('vis-4 fout');
}
}
You need to compare the offset of the two objects
For example,
if ( $("#whale").offset().top == $(".vis-1").offset().top )
{
}
similarly
if ( $("#whale").offset().left == $(".vis-1").offset().left )
{
}

Navigating long un-ordered list

I have this long list with overflow: auto to scroll through it, i set it up for keyboard navigation, the problem is that when using the keyboard it doesn't scroll correctly!
check this jsFiddle
$('ul').keydown(function (e) {
if (e.keyCode == 38) { // up
var selected = $(".selected");
$listItems.removeClass("selected");
if (selected.prev().length == 0) {
selected.siblings().last().addClass("selected");
} else {
selected.prev().addClass("selected");
}
}
if (e.keyCode == 40) { // down
var selected = $(".selected");
$listItems.removeClass("selected");
if (selected.next().length == 0) {
selected.siblings().first().addClass("selected");
} else {
selected.next().addClass("selected");
}
}
})
});
$listItems.click(function () {
if ($(this).is('.selected')) {
return true;
} else {
$('li').removeClass('selected');
$(this).addClass('selected');
}
the behavior i'm looking for is the same behavior of the element when scrolling through a long list of elements using the keyboard this plugin SelectBoxIt show's what i'm looking for.
you can use this code instead, i used animate function to navigate inside the div if the list exceed the width of the ul tag :
http://jsfiddle.net/goldendousa/p6243/13/
$('ul').focus(function() {
if ($('ul li').is('.selected')) {
$('ul li').first().removeClass('selected');
} else {
$('ul li').first().addClass('selected');
}
});
$('ul').keydown(function(e) {
if (e.keyCode == 38) { // up
e.preventDefault();
var selected = $(".selected");
$("ul li").removeClass("selected");
if (selected.prev().length == 0) {
selected.siblings().last().addClass("selected");
var selectedTopOffset = selected.siblings().last().offset().top;
$('div').animate({
scrollTop: selectedTopOffset
}, 200);
} else {
selected.prev().addClass("selected");
var selectedTopOffset = $("div").scrollTop() + selected.position().top - $("div").height()/2 + selected.height()/2;
$('div').animate({
scrollTop: selectedTopOffset
}, 200);
}
}
if (e.keyCode == 40) { // down
e.preventDefault();
var selected = $(".selected");
$("ul li").removeClass("selected");
if (selected.next().length == 0) {
selected.siblings().first().addClass("selected");
if (selected.siblings().first().offset().top < 0) {
$('div').animate({
scrollTop: selected.siblings().first().offset().top
}, 200);
}
} else {
selected.next().addClass("selected");
var selectedTopOffset = $("div").scrollTop() + selected.position().top - $("div").height()/2 + selected.height()/2;
$('div').animate({
scrollTop: selectedTopOffset
}, 200);
}
}
});
$('li').click(function() {
if ($(this).is('.selected')) {
return true;
} else {
$('li').removeClass('selected');
$(this).addClass('selected');
}
});

Expand a div element multiple times

I have a searchbar and the results should be shown on google maps. I want to expand and collapse this map so more results will be visible. But I dont want a normal toggle function.
I want a multiple click action:
First click: Div/Map gets 100px higher
Second click: Div/Map gets another 100px higher
Third click: Div/Map gets 100px smaller,
Fourth click: Div/Map gets another 100px smaller and returns to its original height.
Fifth click: All the previous action should be repeated.
This is what I've got up till now, but After my fourth click nothing happens anymore:
$(function(){
var hits = [0];
$('.kaart-uitklappen').click(function(){...
Fiddle Demo
You don't need as many animate calls, as you basically just change the height modifier. As there are four states essentially (two for going up, two for going down), you need to reset the counter accordingly (i.e., when it reaches 4) - that's done easily with modulo operator.
$(function(){
var hits = -1;
$('.kaart-uitklappen').click(function(){
hits = (hits+1) % 4;
var modifier = hits > 1 ? '-' : '+';
$('#header').animate({height: modifier + '=100px' }, 300);
return false;
});
});
JSFiddle.
You need to make sure your value does not exceed 3, or nothing will happen on subsequent clicks. Also, you should start with your value equal to 0, not [0].
Here is some simplified code with these ideas incorperated: http://jsfiddle.net/XZ7mW/16/
var hits = 0;
$('.kaart-uitklappen').click(function(){
if (hits < 2)
$("#header").animate({'height':'+=100px' }, 300);
else
$("#header").animate({'height':'-=100px' }, 300);
hits = (hits + 1) % 4;
return false;
});
change from hits == number to hits%4 == number
$(function () {
var hits = 0;
$('.kaart-uitklappen').click(function () {
if (hits%4 == 0) {
$("#header").animate({
'height': '+=100px'
}, 300, function () {});
}
if (hits%4 == 1) {
$("#header").animate({
'height': '+=100px'
}, 300, function () {});
}
if (hits%4 == 2) {
$("#header").animate({
'height': '-=100px'
}, 300, function () {});
}
if (hits%4 == 3) {
$("#header").animate({
'height': '-=100px'
}, 300, function () {});
}
hits++;
return false;
});
});
You need to reset your var to 0 once you get to 3 -
if (hits == 3)
{
$("#header").animate({'height':'-=100px' }, 300, function() {});
hits = -1;
}
You also shouldn't be using an array to store hits.
hits = [0]
should be
hits = 0;
http://jsfiddle.net/XZ7mW/10/
On the last if type in this
$("#header").animate({'height': '-=100px'}, 300, function () {});
hits = 0;//make hits 0
return;//return so it doesnt add to hits
}
DEMO
JAVASCRIPT :
$(function () {
var hits = 0;
$('.kaart-uitklappen').click(function () {
if (hits == 0) {
$("#header").animate({
'height': '+=100px'
}, 300);
}
else if (hits == 1) {
$("#header").animate({
'height': '+=100px'
}, 300);
}
else if (hits == 2) {
$("#header").animate({
'height': '-=100px'
}, 300);
}
else {
$("#header").animate({
'height': '-=100px'
}, 300);
hits = 0;
return false;
}
hits++;
return false;
});
});
Fiddle : http://jsfiddle.net/XZ7mW/12/
Here you go :
JSFiddle
$(function () {
var hits = 0;
$('.kaart-uitklappen').click(function () {
if (hits == 0) {
$("#header").animate({
'height': '+=100px'
}, 300, function () {});
hits++;
}
else if (hits == 1) {
$("#header").animate({
'height': '+=100px'
}, 300, function () {});
hits++;
}
else if (hits == 2) {
$("#header").animate({
'height': '-=100px'
}, 300, function () {});
hits++;
}
else if (hits == 3) {
$("#header").animate({
'height': '-=100px'
}, 300, function () {});
hits = 0;
}
return false;
});
});
You need to reset hits when it reaches 3
Assuming you want this to expand, contract and then re-expand:
var hits = [0]; should be var hits = 0; and you will need to test for hits > 3 and set it back to 0;
or use modulus arithmetic in your conditions:
http://jsfiddle.net/XZ7mW/19/
$(function(){
var hits = 0;
$('.kaart-uitklappen').click(function(){
if (hits % 4 == 0) {
$("#header").animate({'height':'+=100px' }, 300, function() {});
}
if (hits % 4 == 1) {
$("#header").animate({'height':'+=100px' }, 300, function() {});
}
if (hits % 4 == 2) {
$("#header").animate({'height':'-=100px' }, 300, function() {});
}
if (hits % 4 == 3) {
$("#header").animate({'height':'-=100px' }, 300, function() {});
}
hits++;
return false;
});
});
Here's how I would do it:
var hits = 0;
$('.kaart-uitklappen').click(function () {
if (hits < 2)
$("#header").animate({'height': '+=100px'}, 300);
else
$("#header").animate({'height': '-=100px'}, 300);
if (++hits == 4)
hits = 0;
return false;
});
http://jsfiddle.net/KX7aq/
Add this at the end to reset the counter:
if(hits==4) {
hits=0;
}
http://jsfiddle.net/XZ7mW/7/
Can be something like this?
var direction = "open";
$('.kaart-uitklappen-button').click(function(){
if (direction == "open"){
$('.kaart-uitklappen').height($('.kaart-uitklappen').height()+100)
if ($('.kaart-uitklappen').height() >= 200){
direction = "close";
}
}else{
$('.kaart-uitklappen').height($('.kaart-uitklappen').height()-100)
if ($('.kaart-uitklappen').height() <= 0){
direction = "open";
}
}
I use kaart-uitklappen-button because you can't click the container if it is closed...

Categories