I can't quite figure out why my code is not working here.
I have an if statements that checks if 1 or more check boxes have been checked, then if its true a function runs. The function allows a bar to slide down when the page scrolls to a certain height.
It works when I first visit the site after a refresh. i.e the bar is not visible, when I scroll, then when I check a box, it becomes visible.
However when I uncheck the box the bar is still visible!
How do I hide it, when the checkbox is unchecked?
I thought a line in the else statement like the below would work, but they don't ( I even tried to add an else if:
$(".userbar").hide(); //OR
$(".userbar").slideUp(); //OR
$(".userbar").off();
Here is my Code:
$(document).on('change', '#est', function (e){
// Get number of checkboxes checked.
var counter = $('input[type="checkbox"]:checked').length;
console.log("Checkboxs checked number: " + counter);
e.preventDefault();
if (counter >= 1 ) {
$(window).scroll(function() {
if ($(this).scrollTop() < 370)
{
$(".userbar").slideUp(100);
}
else
{
$(".userbar").slideDown(100);
}
});
} else if (counter == 0 ){
$(".userbar").hide();
}
});
The first time that counter >= 1, you bind a function to the window "scroll" event, and that function will decide if the bar will be visible or not. Even if later counter evaluates at zero, and you run the .hide(), the scroll handler you registered before will still be there and run again.
An easy way to fix this would be to add something like
else if (counter == 0 ){
$(window).off("scroll");
$(".userbar").hide();
}
Be aware that .off("scroll") will remove any handler for the "scroll" event. If you have others and you want to keep them, you might want to name your handler and remove it individually, like:
function myScrollHandler() {
if ($(this).scrollTop() < 370)
{
$(".userbar").slideUp(100);
}
else
{
$(".userbar").slideDown(100);
}
}
// ...
$(window).scroll(myScrollHandler);
// ...
$(window).off("scroll", myScrollHandler);
Related
Context:
I have a gallery of images. The user can select each image, when they click it, the "selected" attribute is added to the individual element and a new class is added to their chosen image.
The thing is, I want to limit this to only 2 selections being available.
I want to edit my script to only run up until the length is 2 or less. If the length reaches 2, no more Selected attributes to be added and no more class changes to be toggled.
I feel like I'm close. Right now my users can select/deselect but they can just do it too many times. Where am I going wrong?
function NFTSelector() {
$("#NFTGallery2 > img").each(function() {
$(this).on("click", function() {
if($(this).filter("[selected]").length>=2) {
alert('true');
} else
console.log("less than 2 or undefined so letting them choose more");
{
$(this).toggleClass('chosenNFT');
if ($(this).attr('selected')) {
$(this).removeAttr('selected');
} else {
$(this).attr('selected', 'selected');
}
}
})
});
}
I changed my approach, I instead set it up as checkboxes and limited the checkboxes this way
function NFTSelector() {
var limit = 3;
$('#NFTGallery2 > li > input').on('change', function(evt) {
if($('#NFTGallery2 > li > input:checked').length >= limit) {
this.checked = false;
}
});
}
I have some strange task to do. I have to implement car turning lights functionality into my web page. I have two buttons (left and right) and two green arrows (left and right). It should be that: I click left button (left arrow is now hidden) and left arrow should blink. When I click once more time, it should stop animation and be hidden. I just don't know to handle state of button and use it properly. Thanks.
$("#arrow-left").click(function blinker() {
if(something) {
$('#arrow-left-blink').css("visibility", "visible");
$('#arrow-left-blink').fadeOut(500);
$('#arrow-left-blink').fadeIn(500);
setInterval(blinker, 1000);
} else {
//hide
}
}
You should create a closure to save the state across different clicks. Simply create a closure by putting the click handler inside a self-invoking function and declare+initialize your shared variables inside it. Increase your count at the end of the click handler. You can toggle between true and false with the modulus operator '%'. 0%2==0, 1%2==1, 2%2==0, 3%2==1, 4%2==0, ...
(function(){
var counter = 0;
$("#arrow-left").click(function blinker() {
if(counter%2) {// modulus operator will toggle between 0 and 1 which corresponds to truthy or falsy
$('#arrow-left-blink').css("visibility", "visible");
$('#arrow-left-blink').fadeOut(500);
$('#arrow-left-blink').fadeIn(500);
setInterval(blinker, 1000);
} else {
//hide
}
counter++;
});
})();
You could define an outside variable counter.
For example:
$(document).ready(function() {
var counter = 0;
var blinking;
function blinker() {
$('#arrow-left-blink').fadeOut(500);
$('#arrow-left-blink').fadeIn(500);
blinker();
}
$("#arrow-left").click(function() {
counter++;
if (counter % 2 == 1) {
$('#arrow-left-blink').css("visibility", "visible");
blinking = setTimeout(function() {
blinker();
}, 1000);
} else {
clearInterval(blinking);
$('#arrow-left-blink').css("visibility", "hidden");
}
});
});
Here is a JSFiddle link: https://jsfiddle.net/o2xb8Lod/.
I would create a css class to handle the fading and blinking with css animations and just toggleClass on click in Jquery.
I am trying to create a Navigation Bar that slides in and out when clicked on using JavaScript and Greensock. For some reason, the on click action is randomly not working when clicked on at different sizes but sometimes it works perfectly fine.
My code is below, you can find a live example of this navigation at: http://www.kramergraphicdesign.com/Maura_Website/
var resize = function(){
var viewportWidth = $(window).width();
var lastLiWith = $('#logo').width();
console.log(openOrShut + " this is the true false var");
if ($(window).width() >= 0 && $(window).width() <= 639 ) {
console.log("mobile");
$("#logo, #close, .arrow-right").click(function()
{
console.log("mobile-click");
if(openOrShut === false)
{
TweenLite.to("#custom-nav",".5",{x:viewportWidth-lastLiWith});
openOrShut = true;
}
else{
TweenLite.to("#custom-nav",".5",{x:0});
openOrShut = false;
}
});
}
else if ($(window).width() >= 640 ) {
console.log("tablet");
$("#logo, #close, .arrow-right").click(function()
{
console.log("tablet-click");
if(openOrShut === false)
{
TweenLite.to("#custom-nav",".5",{x:400});
openOrShut = true;
}
else{
TweenLite.to("#custom-nav",".5",{x:0});
openOrShut = false;
}
});
}
else if ($(window).width() >= 1025 && $(window).width() <= 10000 ) {
console.log("dekstop");
$("#logo, #close, .arrow-right").click(function()
{
console.log("desktop-click");
if(openOrShut === false)
{
TweenLite.to("#custom-nav",".5",{x:400});
openOrShut = true;
}
else{
TweenLite.to("#custom-nav",".5",{x:0});
openOrShut = false;
}
});
}
};
$(document).ready(resize);
$(window).resize(function(){
resize();
});
First of all, the resize event can occur an awful lot, especially during a drag to resize the window. This means two things:
Minimise the amount of work you do so it runs fast, or debounce the function (e.g. using Lodash) so it only runs after you stop receiving resize events for a short time.
More importantly, you are adding a new click handler every single time.
So the reason it "randomly" doesn't do anything is that whenever you click, you actually run your function to toggle the menu many, many times if you have previously resized the window at all. If that number of times happens to be even, then there is no net effect.
There are probably a number of ways to fix this, but here are two:
Attach a click handler once, but check the width inside the handler to determine how far to animate it to / how to respond differently to different sizes.
Unregister existing click events first (using jQuery's .off()) before re-adding them, so there is only ever the one handler registered. I recommend using an event namespace so you can deregister everything on the namespace at once.
Bonus observation: your condition for the tablet widths means the desktop code will never run, because there is no <= 1024 condition for the tablet block.
I have a button that I want to disable from sending anymore calls to jquery while there is a function "active".
What happens is, every-time a user clicks on the button, the counter gets reduced by 1.
However this happens with a delay, see here the steps;
click button
Button gets disabled
5 seconds later counter gets reduced with one and button changes to enabled.
However, the problem right now is that, even while the button is supposed to be disabled, users can just click is X amount of times, and the counter gets reduced with that X amount of times after 5 seconds.
Meaning the calls still go through.
See here what I tried to do so far, but unfortunately with no success..
$( document ).ready(function() {
var enabled=true;
$(".myButton").click(function(){
if(enabled = true) {
setTimeout(function(){
var i = document.getElementById('counter2');
i.innerHTML = parseInt(i.innerHTML)-1;
$('.progress-bar').css("width", '+=' + '35px');
$(".myButton").attr('disabled','enabled');
$('.myButton').css('opacity', '1');
var enabled=true;
},5000)
$(".myButton").attr('disabled','disabled');
$('.myButton').css('opacity', '0.5');
var enabled=false;
} else { }
});
});
if(enabled = true) {
^
You meant to write == here. Or even better: if (enabled) as enabled is a boolean anyway.
Using = true is an assignment here as well. And as true is truthy the condition will always evaluate to true.
I don't think you need to track a variable to monitor the state of the button, because you already set an attribute to indicated that it's disabled. So you can just use that attribute as an indicator of it's state.
Also, you are doing this behavior on all buttons of class myButton. So I isolated the handler to just event.target which was the button that was clicked.
$(".myButton")
.prop('disabled',false)
.click(function(event){
// get the button that was clicked.
var btn = $(event.target);
if(btn.prop('disabled') === true) {
// it's already disabled, nothing to do
return;
}
// start a 5 second timer
setTimeout(function(){
var i = document.getElementById('counter2');
i.innerHTML = parseInt(i.innerHTML)-1;
//$('.progress-bar').css("width", '+=' + '35px');
// I've never seen += used like this ^^^ does it work?
var bar = $('.progress-bar');
bar.css("width", (bar.width() + 35) + 'px');
// after 5 seconds enable the button
btn.prop('disabled',false);
btn.css('opacity', '1');
},5000);
// disable the button until timer expires.
btn.prop('disabled',true);
btn.css('opacity', '0.5');
});
Here is my code:
var count = 2;
var decrementAmount = 1;
function reduceVariable() {
count -= decrementAmount;
}
$("#button").click(function() {
reduceVariable();
});
if (count == 0) {
$("#avrageReactionTime").html("Hello");
};
When i click my button twice the div that has the id avrageReactionTime does not change to have the text hello. Why do i have this problem...
Right now you test once, instead of testing every time the counter changes.
You must put the if inside the event handler :
$("#button").click(function() {
reduceVariable();
if (count==0) {
$("#avrageReactionTime").html("Hello");
}
});
Note that properly indenting your code makes it obvious.