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.
Related
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);
I am creating a Memory Game for a class at school, and I am using Bootstrap and jQuery. See Github. For testing use this jsfiddle, as the github code will change, I've included it if you would like to fork it for your own purposes.
I've constructed the code on the following logic:
Pick with how many cards you want to play.
Cards get loaded and randomized. Each pair have the same class(card* and glyphicon*).
You click on one card, then on another, and if they match they get discarded, else you pick again.
The problem that I'm currently having is with the third step, namely when you click on the third card it shows the previous two, meaning I need to include something to escape the first click events. At least that was my first suggestion for the problem. If you have other suggestions to completely restructure the third step, please don't shy to elaborate why.
// check if picked cards' classes match
jQuery("[class^=card]").click(function() { //picking the first card
jQuery(this).css('color', '#000');
var firstCard = $(this);
var firstCardClass = $(this).find('[class*=glyphicon]').attr('class').split(' ')[1];
jQuery("[class^=card]").click(function() { //picking the second card
var secondCard = $(this);
var secondCardClass = $(this).find('[class*=glyphicon]').attr('class').split(' ')[1];
console.log(firstCardClass);
console.log(secondCardClass);
if (firstCardClass == secondCardClass) {
console.log("yes")
$(firstCard).css('color', '#005d00'); //make them green
$(secondCard).css('color', '#005d00');
setTimeout(function() {
$(firstCard).css('display', 'none'); //discard
$(secondCard).css('display', 'none');
}, 1000);
}
else {
console.log("no");
$(firstCard).css('color', '#cc0000'); //make them red
$(secondCard).css('color', '#cc0000');
setTimeout(function() {
$(firstCard).css('color', '#fff'); //hide again
$(secondCard).css('color', '#fff');
}, 1000);
}
});
});
Note that the icons should be white as the cards, made them grey to see witch ones match without the need of firebug. If you click on more then two cards you will see what the problem is (if I failed to explain it well). I tried with including click unbind events in the end of each statement, but couldn't make it work.
Try your best! Thanks!
EDITED:
Seems I misunderstood the question so here's how I would go about having such game.
First I'll have my cards to have a structure like this:
<span class="card" data-card-type="one">One</span>
I'll use data-card-type to compare whether two cards are of the same type
I'll have a global variable firstCard which is originally null, if null I assign the clicked card to it and if not I compare the clicked card with it and then whether it's a match or not, I assign null to it meaning another pairing has begun.
I'll do all the logic in one onclick, looks weird to have a click listener inside another makes it to somehow look over-complicated.
var firstCard = null;
$('.card').on('click', function() {
$(this).addClass('selected');
if(!firstCard)
firstCard = $(this);
else if(firstCard[0] != $(this)[0]) {
if(firstCard.data('card-type') == $(this).data('card-type')) {
firstCard.remove();
$(this).remove();
firstCard = null;
//$('.card.selected').removeClass('selected');
}
else {
firstCard = null;
$('.card.selected').removeClass('selected');
}
}
});
jsfiddle DEMO
when a card is clicked, you can add a class to that particular card (e.g. classname clickedcard). Whenever you click another card you can test if there are 2 cards having this clickedcard class. If so, you can take action, for example remove all the clickedcard classes and add one again to the newly clicked one.
In pseudo code I would do it something like this:
jQuery("[class^=card]").click(function() {
if (jQuery('.clickedcard').length == 2) {
// two cards where clicked already...
// take the actions you want to do for 2 clicked cards
// you can use jQuery('.clickedcard')[0] and jQuery('.clickedcard')[1]
// to address both clicked cards
jQuery('.clickedcard').removeClass('clickedcard');
} else {
// no card or only one card is clicked
// do actions on the clicked card and add classname
jQuery(this).addClass('clickedcard');
}
});
You could use `one' (to bind an event once):
$("[class^=card]").one(`click', firstCard);
function firstCard() { //picking the first card
$(this).css('color', '#000');
var firstCard = $(this);
var firstCardClass = $(this).find('[class*=glyphicon]').attr('class').split(' ')[1];
$("[class^=card]").one('click', secondCard);
function secondCard() { //picking the second card
var secondCard = $(this);
var secondCardClass = $(this).find('[class*=glyphicon]').attr('class').split(' ')[1];
console.log(firstCardClass);
console.log(secondCardClass);
if (firstCardClass == secondCardClass) {
console.log("yes")
$(firstCard).css('color', '#005d00'); //make them green
$(secondCard).css('color', '#005d00');
setTimeout(function() {
$(firstCard).css('display', 'none'); //discard
$(secondCard).css('display', 'none');
}, 1000);
}
else {
console.log("no");
$(firstCard).css('color', '#cc0000'); //make them red
$(secondCard).css('color', '#cc0000');
setTimeout(function() {
$(firstCard).css('color', '#fff'); //hide again
$(secondCard).css('color', '#fff');
}, 1000);
}
$("[class^=card]").one(`click', firstCard);
}
}
See the JSFiddle here: http://jsfiddle.net/jL6d2qp6/
I have an animation that is supposed to keep the #top element in a fixed position at the top of the page, except for when the #login element is on the screen. To control this, I am using a javascript function that runs every 10ms and switches out the css class for #top, and when I scroll down, it updates as expected, but when I try to scroll back up, nothing happens.
javascript code in question:
offScreen = function(id, targetValue)
{
var offset = $("#top").offset();
var w = $(window);
var height = $(id).innerHeight();
var finalOffset = (offset.top + height) - w.scrollTop();
if (finalOffset < targetValue)
{
return true;
}
else
{
return false;
}
}
function updateTopMenu()
{
if (offScreen("#login", 81) === false)
{
if($("#top").hasClass("top-bar-absolute") === false)
{
$("#top").addClass("top-bar-absolute");
console.log("added top-bar-absolute");
}
if($("#top").hasClass("top-bar-fixed") === true)
{
$("#top").removeClass("top-bar-fixed");
console.log("removed top-bar-fixed");
}
}
if(offScreen("#login", 81) === true)
{
if($("#top").hasClass("top-bar-absolute") === true)
{
$("#top").removeClass("top-bar-absolute");
console.log("removed top-bar-absolute");
}
if($("#top").hasClass("top-bar-fixed") === false)
{
$("#top").addClass("top-bar-fixed");
console.log("added top-bar-fixed");
}
}
}
$("#top").ready( function() {
setInterval(updateTopMenu, 10);
});
Also, if there is a better way to accomplish this, I'd like it because this feels kind of cheaty.
The easiest way to achieve this is listening to the scroll event on the window. This is called every time the user scrolls. Then you can check whether the user scrolled past the login box, i.e. beyond the login box's height.
If the login box is no longer in the window, assign the #top box a class like .sticky that will change its position to position: fixed. And otherwise remove this class.
Checkout this jsFiddle.
I have got a loop function that slides 2 divs over a 3rd. Working example can be found here: http://jsbin.com/OYebomEB/4/.
Main function:
var elements = ['#pointsbarDiv', '#hotlink1Div', '#pointsbarDiv', '#hotlink2Div'];
function hotlinks_loop(index) {
$(elements[index]).css({top: -75, display: 'block'}).animate({top: '+0'}, 3000, function () {
var $self = $(this);
var currentInstance = this;
setTimeout(function () {
$self.animate({top: $(window).height()}, 3000);
if(currentInstance.hotlinkStop !== true){
hotlinks_loop((index + 1) % elements.length);
}
}, 3000, currentInstance);
});
}
hotlinks_loop(0); // start with the first element
I have some code to disable onclick while hotlink divs are moving:
hotlink2BtnClick: function () {
if ($("#hotlink2Div").css("top") === "0px") {
//do stuff;
} else {
//do stuff;
}
},
However, for the stationary pointsbarDiv I cannot find a solution to disable onclick/mousedown while hotlink divs are sliding over it.
I have tried various 'If's like the the following example:
if (($("#hotlink1Div").css("top") < "76px" && $("#hotlink1Div").css("bottom") < "150px") || ($("#hotlink1Div").css("top") > "-75px" && $("#hotlink1Div").css("bottom") < "75px")))...
I am also wondering if there is way I can just disable onclick/mousedown while divs are moving within the main function provided.
I should mention that I am a newbie to javascript/jquery.
JQuery event functions get passed an event object - you can accept this in your function, and use it to stop propagation:
hotlink2BtnClick: function (ev) {
ev.stopPropagation();
http://api.jquery.com/event.stoppropagation/
Also, if you put your js examples on http://jsfiddle.net, then we can fork it and return it to you fixed.
I managed to do this by creating a an extra div giving it a z-index of -1 and setting visibility to hidden.
Then replacing the points div with this in array for the loop.
Followed by implementing a similar code solution hotlink2BtnClick().
I'm using a slideshow on my website using jquery Cycle 1.
I navigate into my slideshow with #next function. when clicking on my last slide of my slideshow it redirect me to another page (var random_next_url_enfant).
I would like to add the spacebar and the right arrow key to navigation inside my slideshow.
when I add this Js code it works, but on the last slide it starts the slideshow again instead of redirecting me to the next page.
$(document.documentElement).keyup(function (e) {
if (e.keyCode == 39)
{
$('#slider_projets').cycle('next');
}
});
here is my full code using the mouse click. on the last slide, it redirects me to another page, it works perfectly. but I would like to get the same with the spacebar and the right arrow :
$('#slider_projets').cycle({
speed: 600, //temps d'animation
timeout: 0, //fréquence
fx: 'scrollLeft',
//compteur//
pager: "#nav",
after: function(currSlideElement, nextSlideElement, options, forwardFlag) {
$('#counter_1').text((options.currSlide + 1) + ' / ' + (options.slideCount));
slideIndex = options.currSlide;
nextIndex = slideIndex + 1;
prevIndex = slideIndex - 1;
if (slideIndex == options.slideCount - 1) {
/*nextIndex = 0;*/
var random_next_url_enfant = $("#random_next_url_enfant").val();
$('#next').on("click", function(e){
e.preventDefault();
window.location = random_next_url_enfant;
});
}
if (slideIndex === 0) {
prevIndex = options.slideCount - 1;
}
}
});
I think i'm missing something but I can't find what !
here is a jsfiddle :
http://jsfiddle.net/8HsdG/
thanks a lot for your help,
You need access to your slider options outside of your slider, the reason you are not getting to the url is because there is no listener telling it to go there, only the click event.
Here is a jsfiddle that will get you very close, it has everything you need, you just have to fill in the blanks.
http://jsfiddle.net/kkemple/8HsdG/1/
I wrapped your code in an anonymous function so I could declare some scoped variables
(function () {
var slideIndex, slideCount;
// all of your code is here
})();
I then added a before call on your slider:
before: function(currSlideElement, nextSlideElement, options, forwardFlag) {
slideCount = options.slideCount;
},
then added the following code to your key events:
if ( slideIndex == slideCount ) {
//redirect to random url
e.preventDefault;
}
#kkemple, I've resolved the problem... I just had to change :
$(document.documentElement).keyup(function (e) {
if (e.keyCode == 32)
{
$('#slider_projets').cycle('next');
}
});
by
$(document.documentElement).keyup(function (e) {
if (e.keyCode == 32)
{
$("#next").trigger("click");
}
});
and it works perfectly ! anyway thanks for your help !