Here's my problem: when the user clicks on the "validate" button, I send an AJAX request that returns an array of "problematic" elements. From that array, I compute the id of the elements I want to highlight then I "flash" them.
This is nice, it works, but they all flash together.
I want to flash them one after the other, so that it's longer and looks nicer (= not aggressive). I've spent some time trying to use queue() function (I guess it's the way to go) but didn't manage to make it work.
Any idea how to do this?
/* this is the function to retrieve bg color (= not the actual subject) */
jQuery.fn.getBg = function() {
return $(this).parents().filter(function() {
var color = $(this).css('background-color');
return color != 'transparent' && color != 'rgba(0, 0, 0, 0)';
}).eq(0).css('background-color');
};
/* this is my flash function (= not the actual subject) */
function flash(id, font_color, bg_color, nb) {
var bc=$(id).getBg();
var cl=$(id).css('color');
var mx=parseInt(nb);
if (mx<=0) {
mx=1;
}
for (var i=0; i<mx; i++) {
$(id).animate({
backgroundColor: bg_color,
color: font_color
}, 200)
.animate({
backgroundColor: bc,
color: cl
});
};
}
function localOnAjaxError(dataMessage)
{
var msg='';
$('#wait').hide('slow');
/* show the form again and highlight errors */
$('#s-inscrire-form').show('slow', function() {
if (msg!='') {
$('#erreur').fadeIn('slow');
flash('#erreur', "#f9e4c9", "#aa0000", 3);
}
if (dataMessage instanceof Array) {
for (key in dataMessage) {
var m=dataMessage[key];
if(m.indexOf('#error')==0) {
/* show the id... */
$(m).fadeIn('slow', function() {
/* ...then flash the corresponding label */
flash('#label-'+this.id.substr(7), "#ffffff", "#aa0000", 3);
});
}
}
}
});
seConnecterAssigneClicksConnexion();
}
You will need to return the animation queue from your flash function. Then, instead of starting all flashes together in your for-loop (btw: for-in-loops are not suited for arrays), you will need to push them recursively on that queue. What have you tried with .queue()?
You would be correct to use jQuery's queue method. Here's an example that takes all divs and changes their color in sequence.
var theQueue = $({});
$('div').each(function(index, div) {
theQueue.queue('flash', function(next) {
$(div).animate({
backgroundColor: 'red'
}, 500, function() {
next();
});
});
});
theQueue.dequeue('flash');
Live example - http://jsfiddle.net/z7xRe/
There's another question on Stack Overflow that walks through this use case in more detail here - What are queues in jQuery?. See #gnarf's response.
Here's the working solution:
dataMessage = new Array("#erreur-nomprenom", "#erreur-adresse1", "#erreur-cp", "#erreur-ville", "#erreur-tel");
var theQueue = $({});
for (key in dataMessage) {
var m = dataMessage[key];
if (m.indexOf('#erreur') == 0) {
var toFlash = (function(m) {
return function(next) {
$(m).fadeIn('slow', function() {
flash('#label-' + this.id.substr(7), "#ffffff", "#aa0000", 3);
next();
});
}
})(m);
theQueue.queue('flash', toFlash);
}
}
theQueue.dequeue('flash');
Related
First let me describe the project I'm stuggeling with. English is not my foreign language so I do not know the exact name of the effect I am looking for.
Basicly I am creating a bingo type of game where the host can press on a button to start the bingo wheel. Eventually the wheel will stop and the word it has landed on is the chosen word for that round. After that, this word get removed from the game and the game starts over and over untill someone calls a bingo.
I started playing a bit around with some JSON data and how to remove the items from the array etc which is pretty easy to do. But now comes the part where I am struggeling the most. I have to create a kind of function that scrolls through all options like a wheel at a certain speed that eventually decreased in speed so it will land on the chosen word for this round. I created a fiddle with the code I currently have. Note that it's purely created for functionality instead of looks!
var json = {
"titles": [
"PLACEHOLDER_1",
"PLACEHOLDER_2",
"PLACEHOLDER_3",
"PLACEHOLDER_4",
"PLACEHOLDER_5",
"PLACEHOLDER_6",
"PLACEHOLDER_7",
"PLACEHOLDER_8",
"PLACEHOLDER_9",
"PLACEHOLDER_10",
"PLACEHOLDER_11",
"PLACEHOLDER_12",
"PLACEHOLDER_13",
"PLACEHOLDER_14",
"PLACEHOLDER_15"
]
}
$(document).ready(function() {
var app = new Bingo.init();
})
var Bingo = {
viewport: {
isMobile: 0,
isTablet: 0,
isDesktop: 1,
device: 'desktop',
browser: null
}
}
Bingo.init = function() {
Bingo.gameController.init();
};
Bingo.gameController = {
gameNames: {},
init: function() {
Bingo.gameController.general.saveJson();
$('.test').on('click', Bingo.gameController.array.pickRandomNumber)
},
general: {
saveJson: function() {
Bingo.gameController.gameNames = json.titles;
},
//General reset function
resetGame: function() {
Bingo.gameController.general.saveJson;
}
},
array: {
pickRandomNumber: function() {
//reset gamefield
Bingo.gameController.game.buildGame();
var gameNames = Bingo.gameController.gameNames;
var totalNames = gameNames.length;
//Pick a random number
var chosenNumber = Math.floor(Math.random() * totalNames);
Bingo.gameController.array.remove(chosenNumber)
},
remove: function(id) {
//remove chosen name from array
var gameNames = Bingo.gameController.gameNames;
var check = gameNames.indexOf(gameNames[id]);
Bingo.gameController.game.highlightName(id);
if (check != -1) {
gameNames.splice(check, 1);
Bingo.gameController.gameNames = gameNames;
}
}
},
game: {
buildGame: function() {
//build all the array entry's into the div
$('.page.main-game').empty();
var gameNames = Bingo.gameController.gameNames;
for (var i = 0; i < gameNames.length; i++) {
var item = '<div class="name-item" data-id="' + i + '">' + gameNames[i] + '</div>';
$('.page.main-game').append(item);
}
},
highlightName: function(id) {
//highlight the chosen number red
$('.name-item[data-id="' + id + '"]').css('color', 'red');
}
}
}
Fiddle link here
(I hope the link is correct, not using fiddle that much)
So now when you click on the 'play again' button you see that it wil highlight a word. What has to happen is when I press the play again button the red highlight has to go from the first div to the last and so forth untill it eventually stops at a div (which is chosen with the random number or something).
If someone can help me with this or could give me a hint in the right direction please let me know!
EXTRA: The app will eventually get a look like a scrollwheel that the iphone gets when you open a select box (hope you know what I am referring to). So thats why its a wheel of fortune-ish effect. If someone could provide me with the correct name for this let me know so I can adjust the title!
If any information is missing please let me know, i'd be happy to provide it! Thanks in regard!!
The basic ideas are (1) to keep the current index, so you can start the spin every time from that index, where 'spining' is just increasing that index or set to zero when reaching the maximal index; and (2) set a timeout for the next painting, and reduce that timeout everytime, until it's low enough.
JsFiddle Demo
HTML
<p><button onclick="w.spin(w.randomNext(), 8)">SPIN</button></p>
<ul id='wheel'>
<li>$100</li>
<li>$250,000</li>
<li>$25,000</li>
<li>$10,000</li>
<li>$1,000</li>
<li>$5</li>
<li>$2,000</li>
<li>30,000</li>
<li>$40</li>
</ul>
JavaScript
var wheelEl = document.getElementById('wheel');
function Wheel () {
this.current = 4;
}
Wheel.prototype.init = function () {
this.onItem();
}
Wheel.prototype.randomNext = function () {
return Math.floor(Math.random() * wheelEl.children.length);
}
Wheel.prototype.spin = function (next, itemsPerSecond) {
var timeout = setTimeout(onItem.bind(this), (1 / itemsPerSecond) * 1000);
function onItem () {
// stop if speed is low enough
if (itemsPerSecond < 1)
return;
// spin to next item
this.current ++;
if (this.current >= wheelEl.children.length)
this.current = 0;
// paint text
this.onItem();
// reduce speed
clearTimeout(timeout);
itemsPerSecond--;
timeout = setTimeout(onItem.bind(this), (1 / itemsPerSecond) * 1000);
}
}
// paints the index of this.current
Wheel.prototype.onItem = function () {
for (var i = 0 ; i < wheelEl.children.length ; i++)
wheelEl.children[i].style.color = (i == this.current) ? '#6d4321' : '#000000';
}
var w = new Wheel();
w.init();
Basically I'm trying to toggle a function that gradually change background color of div. There's a separate script.js file that is responsible for function gradientify() to run.
I'm just not sure what is the logic to toggle a function...
index.html
<body>
<button type="button" id="btn"></button>
<div style="width: 100px; height: 100px;"></div>
</body>
script.js
$('#btn').click(function() {
$('div').toggle(function() {
$(this).gradientify({
gradients: [
{ start: [49,76,172], stop: [242,159,191] },
{ start: [255,103,69], stop: [240,154,241] },
{ start: [33,229,241], stop: [235,236,117] }
]
});
});
});
The Jquery toggle function toggles the visibility of an element. It basically sets the css property display to display: none. If you want the content inside the "gradientifyied" element to still be visible when you toggle the gradients then you can't use Jquery.toggle.
Sadly the gradientify API doesn't provide any way to cancel the gradients once they are set on an element so the only way to toggle the gradients on an element is to remove it from the DOM all together.
We can create a copy of the clean element before the gradiants are applied and when we want to remove the gradients, we remove the old element from the DOM and insert the copy we kept.
function toggleGradients() {
var gradientTargetCopy = $( ".gradientTarget" ).clone()
var gradientsOff = true;
return function() {
if (gradientsOff) {
$('.gradientTarget').gradientify({
gradients: [
{ start: [49,76,172], stop: [242,159,191] },
{ start: [255,103,69], stop: [240,154,241] },
{ start: [33,229,241], stop: [235,236,117] }
]
});
} else {
$('.gradientTarget').remove()
$('body').append(gradientTargetCopy)
gradientTargetCopy = $( ".gradientTarget" ).clone()
}
gradientsOff = !gradientsOff
}
}
$('#btn').click(toggleGradients());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://codefog.github.io/jquery-gradientify/jquery.gradientify.min.js"></script>
<body>
<button type="button" id="btn">Toggle gradients</button>
<div class="gradientTarget" style="width: 100px; height: 100px;">Hello!</div>
</body>
Just use plain JavaScript.
var x = 3; //Length of amount of color options you want
var bgcolor_num = Math.floor((Math.random() * x) + 1);
setInterval(function () {
if (bgcolor_num === 1) {
bgcolor = "#FF0000";
bgcolor_num = 2;
} else if (bgcolor_num === 2) {
bgcolor = "#00FF00";
bgcolor_num = 3;
} else {
bgcolor = "#0000FF";
bgcolor_num = 1;
}
document.getElementById('whatever').style.backgroundColor = bg_color;
}, 12000);
What happens is that it defines a variable, x, and randomizes a number from 1 to x. Then, an interval (which runs every 12 seconds; 12,000 milliseconds) determines whether the number, bgcolor_num, is 1, 2, 3, or something else. Remember, the amount of options you have has to equal x. If it doesn't, it will run as "else" and will start back at color option #1.
Make sure you have an ID set for your div and reconfigure the part that actually triggers the change!
If you want an example of this happening, you can always go to my website typrograms.com/RGB.html and right-click, view-source! I use a similar method, and it slowly changes the color.
I have created a page where I have multiple functionality done but stuck with timing of it, if you see the page example here in JSFiddle.
When you open the page, it will first run a loader and when the loader is complete there are multiple boxes, which is showing one by one but in currently its not happening, Loader is loading fine and then in the next step where centered columns has to appear one by one, the first four columns loads by default and then other div loads one by one.
My question is, how can I execute a function and execute another another function once the previous is complete.
For loader I have the following:
//--------- process bar animation
var showText = function (target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index++]);
setTimeout(function () { showText(target, message, index, interval); }, interval);
}
}
var width = 100,
perfData = window.performance.timing, // The PerformanceTiming interface represents timing-related performance information for the given page.
EstimatedTime = -(perfData.loadEventEnd - perfData.navigationStart),
time = parseInt((EstimatedTime/1000)%60)*100;
showText("#msg", "Welcome to the Company Group", 0, width);
// Loadbar Animation
$(".loadbar").animate({
width: width + "%"
}, time);
// Loadbar Glow Animation
$(".glow").animate({
width: width + "%"
}, time);
// Percentage Increment Animation
var PercentageID = $("#precent"),
start = 0,
end = 100,
durataion = time;
animateValue(PercentageID, start, end, durataion);
function animateValue(id, start, end, duration) {
var range = end - start,
current = start,
increment = end > start? 1 : -1,
stepTime = Math.abs(Math.floor(duration / range)),
obj = $(id);
var timer = setInterval(function() {
current += increment;
$(obj).text(current + "%");
//obj.innerHTML = current;
if (current == end) {
clearInterval(timer);
}
}, stepTime);
}
// Fading Out Loadbar on Finised
setTimeout(function(){
$('.preloader-wrap').fadeOut(300);
$('.loader-wrap').fadeOut(300);
$('.main-wrapper').fadeIn(300);
$('body').addClass('bg');
}, time);
For showing div one by one in next step I have the following code:
$(".column-wrapper").each(function(index) {
var $this = $(this);
setTimeout(function () { $this.addClass("show"); }, index * 1000);
});
I use trigger and on for those kind of things. You had a lot of code, so sorry, I didn't want to read all of that but this is a simplified example.
https://jsfiddle.net/2d6p4L6k/1/
$(document).ready(function(){
var action = function(){
$('div.one').css('background-color', 'green');
/* do whatever you want to do */
/* then trigger(call) another function */
$(document).trigger('hello-action');
};
var hello = function() {
$('div.two').css('background-color', 'fuchsia');
};
/* just listen if anything triggers/calls "hello-action" */
/* if so call function named hello */
$(document).on('hello-action', hello);
setTimeout(action, 1500);
});
div {
width: 50px;
height: 50px;
background-color: orange;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="one">one</div>
<div class="two">two</div>
Note: To keep it simple we trigger and listen on $(document) which is really just to keep it simple. A better approach would be to have a wrapper element, and then you can do exactly the same (trigger and listen) just on that element and not on the entire document. You can find more details on the jQuery API .trigger()
$('.pictures a').click(function () {
var path = "place/of/images";
var pics = ['pic1.JPG',
'pic2.JPG',
'pic3.JPG',
'pic4.JPG'];
var i = 0;
var numberOfPics = pics.length - 1;
var vaheta = setInterval(function () {
$('body').css({ backgroundImage: 'url(' + path + pics[i] + ')' });
if (i == numberOfPics) {
i = 0;
} else {
i++;
}
}, 3000);
return false;
});
This is the code that is currently just changing background images for me. Now I found a topic here where it says you have to load the pictures as etc and there was this fiddle, http://jsfiddle.net/RnqQL/1/, this one, that is exactly what I want to do, but I don't quite know how to combine these two (my code and the fiddle).
The images will actually later be loaded with JSON from the server depending on the id of the link the person clicked to get this slideshow, this is too overwhelming for me...
I created fiddle at http://jsfiddle.net/xMrp3/1/
You can modify and use. I try to explain what i did with comments.
$('.pictures a').click(function () {
var path = "http://elegantthemes.com/preview/InStyle/wp-content/uploads/2008/11/";
$("#wrap").empty(); // clear wrap div content
$.getJSON('/echo/json/', function (pics) { // get json data
var pics = ['s-1.jpg', 's-5.jpg', 's-3.jpg']; // i override json response for demo
$.each(pics, function(i, pic) { // loop through pics array
$('<img/>').attr('src', path + pic).appendTo($("#wrap")); // append all images to #wrap div
});
if (animTimeout == null) // if we didnt started anim yet
anim(); // start animation
});
return false;
});
var animTimeout = null;
function anim() {
$("#wrap img").first().appendTo('#wrap').fadeOut(500);
$("#wrap img").first().fadeIn(500);
animTimeout = setTimeout(anim, 700);
}
Newbie here to javascript. I tried to follow the link here :
How to randomly assign a color on hover effect
but I failed to replicate the same effect on my #menu_4645908 nav link...
I use #menu_4645908.red:hover but to no effect.
Note: I did change the variables of the classes from colour to padding , i just used the same class name while i work, will change when its working..
any idea where i went wrong?
[UPDATE]
This is the css im using, copied from the thread,
#menu_4645908.green:hover { color: #1ace84; }
#menu_4645908.purple:hover { color: #a262c0; }
#menu_4645908.teal:hover { color: #4ac0aa; }
#menu_4645908.violet:hover { color: #8c78ba; }
#menu_4645908.pink:hover { color: #d529cd; }
And this is the javascript
$(document).ready(function() {
$("a").hover(function(e) {
var randomClass = getRandomClass();
$(e.target).attr("class", randomClass);
});
});
function getRandomClass() {
//Store available css classes
var classes = new Array("green", "purple", "teal", "violet", "pink");
//Give a random number from 0 to 5
var randomNumber = Math.floor(Math.random()*6);
return classes[randomNumber];
}
There seem to have two problems in your code:
jQuery has an addClass() function that does exactly what you want
The class should not be assigned on hover, but rather at the loading of page
So try this instead: (JsFiddle)
$(document).ready(function() {
$.each($("a"), function(index, element){
$(this).addClass(getRandomClass());
});
});
function getRandomClass() {
//Store available css classes
var classes = new Array("green", "purple", "teal", "violet", "pink");
//Give a random number from 0 to 5
var randomNumber = Math.floor(Math.random()*6);
return classes[randomNumber];
}
EDIT: as user Semicolon said in the comments, this only works if you only wanted the random classes to be assigned at pageload.
In that case, you could just assign a specific color each time:
$(document).ready(function() {
("a").hover(function(){
$(this).css('color', getRandomColor());
}, function(){
$(this).css('color', ''); // Reverts to default color
});
});
function getRandomColor() {
var colors = new Array("#1ace84", "#a262c0", "#4ac0aa", "#8c78ba", "#d529cd");
var randomNumber = Math.floor(Math.random()*colors.length);
return colors[randomNumber];
}