I am making a javascript/jQuery condition to make the header drop down once a user clicks a button ("Buy Now") only when they can't see the header (200px down). My problem is that when the user scrolls more than 200px even if they scroll back up the code still exectues. Here is my code, thanks.
$(function() {
$(document).scroll(function() {
var y = $(window).scrollTop();
console.log(y);
if (y >= 200) {
$('.product__add-to-cart-button').click(function() {
// your statements;
$(".site-header").addClass("site-header--fixedd").removeClass("site-header--transparent");
$("#crazy-pineapple, #coco-twist, #crunchy-joy, #nutty-chia").css('margin-top', 143);
setTimeout(function() {
$(".site-header__cart-bubble").removeClass("bubblenormal").addClass("bubblevisible");
}, 300);
setTimeout(function() {
$(".site-header__cart-bubble").removeClass("bubblevisible").addClass("bubblenormal");
}, 700);
setTimeout(function() {
$(".site-header").removeClass("site-header--fixedd");
$(".site-header").addClass("site-header--fixeddd");
}, 1200);
setTimeout(function() {
$("#crazy-pineapple, #coco-twist, #crunchy-joy, #nutty-chia").css('margin-top', 0);
$(".site-header").addClass("site-header--transparent");
$(".site-header").removeClass("site-header--fixedd");
$(".site-header").removeClass("site-header--fixeddd");
}, 1600);
});
}
});
});
There are a few big NO's in your code.
You should NEVER add a event handler in a scroll/resize function! Why? Because you keep stacking them once you do the resizing/scrolling.
At the moment you apply multiply click events to .product__add-to-cart-button which I assume you don't want.
In addition there is no point to your scroll event at the moment. You can just create an if statement inside the click event if the scrollTop() is bigger than 200 and you can remove the scroll event all together.
In addition you must get the habit of caching objects if you plan to use them multiply times. Any object used more than once must be cached.
And here is how should your code look if we take in consideration all of the above remarks:
$(function() {
var $win = $(window);
var $siteHeader = $(".site-header");
var $siteHeaderCartBuble = $(".site-header__cart-bubble");
var $group = $("#crazy-pineapple, #coco-twist, #crunchy-joy, #nutty-chia");
$('.product__add-to-cart-button').on('click',function() {
if ($win.scrollTop() <= 200) {
return false
};
$siteHeader
.addClass("site-header--fixedd")
.removeClass("site-header--transparent");
$group.css('margin-top', 143);
setTimeout(function() {
$siteHeaderCartBuble
.removeClass("bubblenormal")
.addClass("bubblevisible");
}, 300);
setTimeout(function() {
$siteHeaderCartBuble
.removeClass("bubblevisible")
.addClass("bubblenormal");
}, 700);
setTimeout(function() {
$siteHeader
.removeClass("site-header--fixedd")
.addClass("site-header--fixeddd");
}, 1200);
setTimeout(function() {
$group.css('margin-top', 0);
$siteHeader
.addClass("site-header--transparent")
.removeClass("site-header--fixedd")
.removeClass("site-header--fixeddd");
}, 1600);
});
})
Related
this script runs at the beginning of a website. If the user starts scrolling, some css animations start. After the classes are added (this all works so far), I want an auto-scroll to the next anchor.
The hasClass("makeVisible") == true part also works, but after scrolling to my anchor I can't scroll anymore. The page sticks.
Anybody an idea? Thanks in advance!
$(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 100) {
$('.navBg').addClass('activate');
$('.logo h2').addClass('removeText');
$('.logo').addClass('animate');
$('.secondTitle').addClass('maker');
setTimeout(function() {
$('.animate').addClass('moveLeft');
}, 500);
setTimeout(function() {
$('.maker').addClass('makeVisible');
}, 700);
if ($('.maker').hasClass("makeVisible") == true) {
$('html, body').delay(300).animate({
scrollTop: $('#secondPoint').offset().top
}, 2000);
} else {}
} else {
$('.animate').removeClass('moveLeft');
$('.navBg').removeClass('activate');
$('.logo h2').removeClass('removeText');
$('.logo').removeClass('animate');
$('.maker').removeClass('makeVisible');
$('.secondTitle').removeClass('maker');
}
});
});
I am building a website using one html file and manipulating the contents with javascript. So certain actions trigger the next page to form. In this case I currently have a button on the bottom of each "page" which links to the next one I am trying to now integrate these same functions in a switch statement which works on scroll. However I cannot get this to work. I am also trying to put in an else if statement that is scroll is less then 0 the jquery loads the previous window.
var currentView = 'pageOne';
var display = $('.pageOne').css('display');
if (display == 'block') {
changePageOne();
}
var display2 = $('.pageTwo').css('display');
if (display2 == 'block') {
changePageTwo();
}
$(window).scroll(function(){
if($(window).scrollTop() > 0){
switch(currentView){
case 'pageOne':
changePageOne();
break;
case "pageTwo":
changePageTwo();
break;
case "pageThree":
changePageThree();
}
}
});
function changePageOne(){
$('.fadeInRight').toggleClass("fadeOutLeft").toggleClass("fadeInRight");
$('.fadeInLeft').toggleClass("fadeOutRight").toggleClass("fadeInLeft");
$('.fadeInUp').toggleClass("fadeOutDown").toggleClass("fadeInUp");
$('.fadeInDown').toggleClass("fadeOutUp").toggleClass("fadeInDown");
setTimeout(function() {
$('.slideOutRight').toggleClass("slideInLeft").toggleClass("slideOutRight");
$('.slideOutLeft').toggleClass("slideInRight").toggleClass("slideOutLeft");
$('.slideOutUp').toggleClass("slideInDown").toggleClass("slideOutUp");
$('.slideOutDown').toggleClass("slideInUp").toggleClass("slideOutDown");
$('.pageTwo').css("display", "block");
}, 300);
setTimeout(function() {
$('.pageOne').css("display", "none");
}, 300);
currentView = "pageOne";
};
function changePageTwo(){
$('.slideInRight').toggleClass("slideOutRight").toggleClass('slideInRight');
$('.slideInLeft').toggleClass("slideOutLeft").toggleClass('slideInLeft');
$('.slideInUp').toggleClass("slideOutDown").toggleClass('slideInUp');
$('.slideInDown').toggleClass("slideOutUp").toggleClass('slideInDown');
$('.fadeOutRight').toggleClass("fadeInRight").toggleClass('fadeOutRight');
$('.fadeOutLeft').toggleClass("fadeInLeft").toggleClass('fadeOutLeft');
$('.fadeOutDown').toggleClass("fadeInDown").toggleClass('fadeOutDown');
$('.fadeOutUp').toggleClass("fadeInUp").toggleClass('fadeOutUp');
$('.pageThree').css("display", "block");
setTimeout(function() {
$('.pageTwo').css("display", "none");
}, 300);
currentView = "pageTwo";
};
function changePageThree(){
$('.fadeInRight').toggleClass("fadeOutLeft").toggleClass("fadeInRight");
$('.fadeInLeft').toggleClass("fadeOutRight").toggleClass("fadeInLeft");
$('.fadeInUp').toggleClass("fadeOutDown").toggleClass("fadeInUp");
$('.fadeInDown').toggleClass("fadeOutUp").toggleClass("fadeInDown");
setTimeout(function() {
$('.slideOutRight').toggleClass("slideInLeft").toggleClass("slideOutRight");
$('.slideOutLeft').toggleClass("slideInRight").toggleClass("slideOutLeft");
$('.slideOutUp').toggleClass("slideInDown").toggleClass("slideOutUp");
$('.slideOutDown').toggleClass("slideInUp").toggleClass("slideOutDown");
$('.pageThree').css("display", "block");
}, 300);
setTimeout(function() {
$('.pageTwo').css("display", "none");
}, 300);
currentView = "pageThree";
};
I have provided below methods with some changes made in your code. Using https://stackoverflow.com/a/14193343/3709922 this answer, you can track scroll events and using below methods, you can change pages. Hope it helps.
function changePageOne(){
$('.fadeInRight').toggleClass("fadeOutLeft").toggleClass("fadeInRight");
$('.fadeInLeft').toggleClass("fadeOutRight").toggleClass("fadeInLeft");
$('.fadeInUp').toggleClass("fadeOutDown").toggleClass("fadeInUp");
$('.fadeInDown').toggleClass("fadeOutUp").toggleClass("fadeInDown");
setTimeout(function() {
$('.slideOutRight').toggleClass("slideInLeft").toggleClass("slideOutRight");
$('.slideOutLeft').toggleClass("slideInRight").toggleClass("slideOutLeft");
$('.slideOutUp').toggleClass("slideInDown").toggleClass("slideOutUp");
$('.slideOutDown').toggleClass("slideInUp").toggleClass("slideOutDown");
$('.pageTwo').css("display", "block");
}, 300);
setTimeout(function() {
$('.pageOne').css("display", "none");
}, 300);
currentView = "pageTwo"; // changed to pageTwo
}
function changePageTwo(){
$('.slideInRight').toggleClass("slideOutRight").toggleClass('slideInRight');
$('.slideInLeft').toggleClass("slideOutLeft").toggleClass('slideInLeft');
$('.slideInUp').toggleClass("slideOutDown").toggleClass('slideInUp');
$('.slideInDown').toggleClass("slideOutUp").toggleClass('slideInDown');
$('.fadeOutRight').toggleClass("fadeInRight").toggleClass('fadeOutRight');
$('.fadeOutLeft').toggleClass("fadeInLeft").toggleClass('fadeOutLeft');
$('.fadeOutDown').toggleClass("fadeInDown").toggleClass('fadeOutDown');
$('.fadeOutUp').toggleClass("fadeInUp").toggleClass('fadeOutUp');
$('.pageThree').css("display", "block");
setTimeout(function() {
$('.pageTwo').css("display", "none");
}, 300);
currentView = "pageThree"; // changed to pageThree
}
function changePageThree(){
$('.fadeInRight').toggleClass("fadeOutLeft").toggleClass("fadeInRight");
$('.fadeInLeft').toggleClass("fadeOutRight").toggleClass("fadeInLeft");
$('.fadeInUp').toggleClass("fadeOutDown").toggleClass("fadeInUp");
$('.fadeInDown').toggleClass("fadeOutUp").toggleClass("fadeInDown");
setTimeout(function() {
$('.slideOutRight').toggleClass("slideInLeft").toggleClass("slideOutRight");
$('.slideOutLeft').toggleClass("slideInRight").toggleClass("slideOutLeft");
$('.slideOutUp').toggleClass("slideInDown").toggleClass("slideOutUp");
$('.slideOutDown').toggleClass("slideInUp").toggleClass("slideOutDown");
$('.pageFour').css("display", "block");
}, 300);
setTimeout(function() {
$('.pageThree').css("display", "none");
}, 300);
currentView = "pageFour"; // changed to pageFour
}
Edit:
The above methods will only help to transition in forward order, i.e. from one to two and from two to three and so on. For backward transition, you have to create another methods same as these methods, but just changing the currentView order, and
$('.pageTwo').css("display", "block");
setTimeout(function() {
$('.pageOne').css("display", "none");
}, 300);
these lines to move in reverse (backward) order and check the scroll condition if user is scrolling backward or forward to make transition to backward of forward respectively.
var random;
var squareArray = [$('#square1'),$('#square2'),$('#square3'),$('#square4')];
var randomOrder = [];
var i = 0;
var j = 0;
function computerPlays() {
random = Math.floor(Math.random() * 4);
randomOrder.push(random);
makeSquareBlink();
userPlays();
}
function makeSquareBlink() {
setTimeout(function() {
var randomSquare = squareArray[randomOrder[i]];
randomSquare.css('opacity', '0.5');
setTimeout(function() {
randomSquare.css('opacity', '1');
}, 300);
i++;
if (i < randomOrder.length)
makeSquareBlink();
}, 500);
}
function userPlays() {
$('#square1').on('click', function() {
if (randomOrder[j] === 0) {
$('#square1').css('opacity', '0.5');
setTimeout(function() {
$('#square1').css('opacity', '1');
}, 300);
}
else {
$('#counter').text('!!');
makeSquareBlink();
}
});
$('#square2').on('click', function() {
if (randomOrder[j] === 1) {
$('#square2').css('opacity', '0.5');
setTimeout(function() {
$('#square2').css('opacity', '1');
}, 300);
}
else {
$('#counter').text('!!');
makeSquareBlink();
}
});
$('#square3').on('click', function() {
if (randomOrder[j] === 2) {
$('#square3').css('opacity', '0.5');
setTimeout(function() {
$('#square3').css('opacity', '1');
}, 300);
}
else {
$('#counter').text('!!');
makeSquareBlink();
}
});
$('#square4').on('click', function() {
if (randomOrder[j] === 3) {
$('#square4').css('opacity', '0.5');
setTimeout(function() {
$('#square4').css('opacity', '1');
}, 300);
}
else {
$('#counter').text('!!');
makeSquareBlink();
}
});
}
function reset() {
randomOrder = [];
i = 0;
}
$('button').click(function() {
reset();
computerPlays();
});
Why it isn't possible to change the css property of randomSquare variable in makeSquareBlink function? Is there any way to do it? Edit #001: Added the full code now Still not working help. Man stackoverflow wants more details wth should I type more ? FTHISS hit FML Fk everything letme post it bro. YOu're my last hope ://
I guess the goal of the game is to click the same square like the computer before. Right?
One problem with your code is that makeSquareBlink() increases i by one when the computer plays. Then when the user plays and hits the wrong square inside makeSquareBlink() you try to access randomOrder[i] which is in fact calling randomOrder[1] which returns undefined as randomOrder only contains one element so far. Thus squareArray[randomOrder[1]] gives back undefined and undefined.css(...) is the error you get.
You may fix it by adding a param to your makeSquareBlink() method so that it reads
function makeSquareBlink(p) {
setTimeout(function() {
var randomSquare = squareArray[randomOrder[p]];
randomSquare.css('opacity', '0.5');
setTimeout(function() {
randomSquare.css('opacity', '1');
}, 300);
p++;
if (p < randomOrder.length)
makeSquareBlink(p);
}, 500);
}
And then inside computerPlays you call it with i as param and inside userPlays with j. Haven't tested it but I don't want to solve your homework completely ;)
Also rethink the event listener attachment inside userPlays() as this will attach click listeners each time the method is called. I guess that's not what you want. Maybe try jQuerys one() method here. Or better restructure your code so that the click-listeners are attached only once.
BTW here a fiddle that helped me debug your code: https://jsfiddle.net/hm69ff0a/
I'm hoping a Javascript wiz can help a fellow citizen out with resolving a problem. I've a fairly straight forward function. When I scroll down by 1px I would like to apply a bounceDown class, this will run for 5 seconds and the class will then disappear for future running of the same function.
When I scroll up from that current scroll position I would like the bounceUp effect to apply. However the issue is I think the bounceUp effect only works once you scroll past the original scroll but in addition to this if the previous function is still running on it's 5 second transition then it gets jumpy as it's trying to run two classes at the same time so there almost needs to be a delay applied.
Does anyone think they can help, I'd gratefully appreciate it.
<script>
(function($){
$.fn.extend({
addTemporaryClass: function(className, duration) {
var elements = this;
setTimeout(function() {
elements.removeClass(className);
}, duration);
return this.each(function() {
$(this).addClass(className);
});
}
});
})(jQuery);
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 1) {
$(".spanner").addTemporaryClass("BounceDown", 5000);
}
else if (scroll <= 1) {
$(".spanner").addTemporaryClass("BounceUp", 5000);
}
});
</script>
What about a boolean variable that is 'true' when addTemporaryClass is running? So:
(function($){
var classAdded = false; //New
$.fn.extend({
addTemporaryClass: function(className, duration) {
classAdded = true; //New
var elements = this;
setTimeout(function() {
elements.removeClass(className);
classAdded = false; //New
}, duration);
return this.each(function() {
$(this).addClass(className);
});
}
});
})(jQuery);
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 1 /*New*/ && !classAdded /*New*/) {
$(".spanner").addTemporaryClass("BounceDown", 5000);
}
else if (scroll <= 1 /*New*/ && !classAdded /*New*/) {
$(".spanner").addTemporaryClass("BounceUp", 5000);
}
});
I have the following function :
function loadInfoBubble(aString)
{
$('#infoBubble').html('<h3>info :</h3><p>'+aString+'</p>');
infoBubble.style.display = "block";
var opacity = 9;
var vanishBlock = null;
var theTimeOut = setTimeout(function()
{
vanishBlock = setInterval(function()
{
if(opacity > 0)
{
opacity--;
}
infoBubble.style.opacity = "0."+opacity;
}, 100);
}, 7000);
var theTimeOut2 = setTimeout(function()
{
infoBubble.style.display = "none";
clearInterval(vanishBlock);
}, 9000);
}
This function is linked to a button by an onclick event.
The function is supposed to display a block which contains a sentence for 9 seconds, and after 7 seconds it starts to vanish.
It behaves normally for the first call, but if I click several times, it doesn't work anymore, even if I let the timeOuts end.
I don't understand why because each timeout or interval belongs to its own variable.
Your code never resets the opacity back to 1. Also, if you trigger the action again before a cycle is finished, the previous cycle isn't canceled. Thus if you trigger the bubble, and then trigger it again 5 seconds later, the first cycle will still run and the bubble will disappear in only 2 seconds. If you click again, the bubble will be faded by the cycle that started on the second click.
I think what you need to do is save the timer references with the bubble object itself, and then reset everything when you want to start a display cycle. You can use the jQuery .data() method for that:
function loadInfoBubble(aString) {
var $bubble = $("#infoBubble");
$bubble
.html('<h3>info :</h3><p>' + aString + '</p>')
.css({ display: "block", opacity: 1 });
var opacity = 9;
var timers = $bubble.data("timers") || {};
clearInterval(timers.vanishBlock);
clearTimeout(timers.showTimer);
clearTimeout(timers.clearTimer);
timers = {
showTimer: setTimeout(function() {
timers.vanishBlock = setInterval(function() {
if (opacity > 0) {
opacity--;
}
$bubble.css({ opacity: "0." + opacity });
}, 100);
}, 7000),
clearTimer: setTimeout(function() {
$bubble.css({ display: "none" });
clearInterval(timers.vanishBlock);
}, 9000)
};
$bubble.data("timers", timers);
}
jsfiddle