Select random function - javascript

I have a list of functions:
function randomiseiconscycle1() {
$("#iconTwoContainer img, #iconFiveContainer img, #iconSevenContainer img").fadeIn(300);
setTimeout( function(){
$("#iconTwoContainer img, #iconFiveContainer img, #iconSevenContainer img").fadeOut(300);
},200);
function randomiseiconscycle2() {
$("#iconOneContainer img, #iconSixContainer img").fadeIn(300);
setTimeout( function(){
$("#iconOneContainer img, #iconSixContainer img").fadeOut(300);
},200);
}
everytime i click this button i have i want to activate one of the 8 functions (like above) randomly.
any help would be much appreicated.

Put references to the functions in an array:
var iconcycle = [
randomiseiconscycle1, randomiseiconscycle2,
randomiseiconscycle3, randomiseiconscycle4,
randomiseiconscycle5, randomiseiconscycle6,
randomiseiconscycle7, randomiseiconscycle8
];
Now you can pick one at random and call it:
iconcycle[Math.floor(Math.random() * iconcycle.length)]();

in javascript functions are just objects, so you can do some fun things with them (such as selecting one at random)
This should be enough to get you started:
http://jsfiddle.net/jvGkp/
var arrayOfFuncs = [];
arrayOfFuncs.push(function () { alert('first func!'); });
arrayOfFuncs.push(function () { alert('second func!'); });
arrayOfFuncs.push(function () { alert('third func!'); });
arrayOfFuncs[0]();

I think you're looking for something like this...
function callRandomFunction() {
var random = Math.floor(Math.random()*8);
switch(random){
case 0:
randomiseiconscycle1();
break;
case 1:
....
...
}
}

You can create an array of functions, generate a random number and use that to call one of those functions:
http://jsfiddle.net/4PfAC/1/

Assumed that you have 2 functions i.e. randomiseiconscycle1 and randomiseiconscycle2
$(function(){
var totalfunc=2; // if more than 2 functions than increase the number.
function randomiseiconscycle1() {
var name=arguments.callee.name;
alert(name);
setTimeout( function(){
alert(name);
},200);
}
function randomiseiconscycle2() {
var name=arguments.callee.name;
alert(name);
setTimeout( function(){
alert(name);
},200);
}
$('button').on('click', function(){
var randomnumber=Math.floor(Math.random()*totalfunc+(1));
var func="randomiseiconscycle"+randomnumber;
eval(func)();
});
});​
A fiddle is here.

Related

Function when multiple elements have been clicked

I want a to have an animation only when seven elements have been click. Here is the code but it doesn't work:
var animp5 = function () {
var i = 0;
$("#ans1_p5").on('click', function () {
i = i + 1;
$("#ans1_p5").fadeOut(800);
$("#correct1_p5").fadeIn(1000);
});
$("#ans2_p5").on('click', function () {
i = i + 1;
$("#ans2_p5").fadeOut(800);
$("#correct2_p5").fadeIn(1000);
});
$("#ans3_p5").on('click', function () {
i = i + 1;
$("#ans3_p5").fadeOut(800);
$("#correct3_p5").fadeIn(1000);
});
$("#ans5_p5").on('click', function () {
i = i + 1;
$("#ans5_p5").fadeOut(800);
$("#correct4_p5").fadeIn(1000);
});
$("#ans7_p5").on('click', function () {
i = i + 1;
$("#ans7_p5").fadeOut(800);
$("#correct5_p5").fadeIn(1000);
});
$("#ans9_p5").on('click', function () {
i = i + 1;
$("#ans9_p5").fadeOut(800);
$("#correct6_p5").fadeIn(1000);
});
$("#ans10_p5").on('click', function () {
i = i + 1;
$("#ans10_p5").fadeOut(800);
$("#correct7_p5").fadeIn(1000);
});
if (i === 7) {
$("#ans4").fadeOut(800);
$("#ans6").fadeOut(800);
$("#ans8").fadeOut(800);
$("#wrong1_p5").fadeIn(1000);
$("#wrong2_p5").fadeIn(1000);
$("#wrong3_p5").fadeIn(1000);
$("#cor_p5").fadeIn(1000);
}
};
I have tried other solutions (like .data('clicked') or .attr('clicked') but they didn't work either.
You can use observer design pattern in javascript to achieve this the right way.
First create handlers, subscribe and execute functions and then you can subscribe waht ever you like in your case its comparison i===7. execute fade.execute after every click to validate.
Also it's advisable to use class selectors than id selectors in your case. As id selectors will be unmanageable and you will end up with a lot of duplicate code.
But for the sake of your question observer is your way to go.
jsFiddle
function Fade() { // Create Fade handlers
this.handlers = []; // observers
}
Fade.prototype = { // define subscribe and execute
subscribe: function(fn) {
this.handlers.push(fn);
},
execute: function(o, thisObj) {
var scope = thisObj || window;
this.handlers.forEach(function(item) {
item.call(scope, o);
});
}
};
var fade = new Fade();
fade.subscribe(function(){ // pass function you want to subscribe
console.log(i);
if(i===7){
$("#ans4").fadeOut(800);
$("#ans6").fadeOut(800);
$("#ans8").fadeOut(800);
$("#wrong1_p5").fadeIn(1000);
$("#wrong2_p5").fadeIn(1000);
$("#wrong3_p5").fadeIn(1000);
$("#cor_p5").fadeIn(1000);
}
});
var animp5 = (function(){
var i = 0;
$("#ans1_p5").on('click',function(){
i=i+1;
$("#ans1_p5").fadeOut(800);
$("#correct1_p5").fadeIn(1000);
fade.execute(); // execute to check if condition met
});
$("#ans2_p5").on('click',function(){
i=i+1;
$("#ans2_p5").fadeOut(800);
$("#correct2_p5").fadeIn(1000);
fade.execute();
});
$("#ans3_p5").on('click', function(){
i=i+1;
$("#ans3_p5").fadeOut(800);
$("#correct3_p5").fadeIn(1000);
fade.execute();
});
$("#ans5_p5").on('click', function(){
i=i+1;
$("#ans5_p5").fadeOut(800);
$("#correct4_p5").fadeIn(1000);
fade.execute();
});
$("#ans7_p5").on('click', function(){
i=i+1;
$("#ans7_p5").fadeOut(800);
$("#correct5_p5").fadeIn(1000);
fade.execute();
});
$("#ans9_p5").on('click', function(){
i=i+1;
$("#ans9_p5").fadeOut(800);
$("#correct6_p5").fadeIn(1000);
fade.execute();
});
$("#ans10_p5").on('click', function(){
i=i+1;
$("#ans10_p5").fadeOut(800);
$("#correct7_p5").fadeIn(1000);
fade.execute();
});
})();
Thanks for your answers.
As I have not much experience working with jquery I was unable to code your solution but I found a new one that works perfect. I put the "if" inside every click function so each time I click, code checks if the condition has been fulfilled and once this happens run the appropriate code.
Thanks again

jQuery: index slice function in iterations

I have a slice function set up, calling the index of a .test to fade in the .test divs in blocks of 5. There's a demo here: http://jsfiddle.net/neal_fletcher/JT4KB/2/
jQuery:
$(document).ready(function () {
$('.test').each(function (index) {
$('.test').slice(0, 5).delay(500).fadeIn(300);
$('.test').slice(5, 10).delay(1000).fadeIn(300);
$('.test').slice(10, 15).delay(1500).fadeIn(300);
});
});
This works fine, but as the site will be content managed I want a more compact solution, thus instead of having to write a function for every 5 divs, is there a way to call this function by adding an extra 500 onto the delay for every 5 divs? If that makes sense? Any suggestions would be greatly appreciated!
Here you go sir.
http://jsfiddle.net/JT4KB/17/
$(document).ready(function () {
setTimeout(function () {
$('.test').each(function (i) {
var delay = Math.floor(i/5)*500 + 500;
$(this).delay(delay).fadeIn(300);
});
}, 1000);
});
You can use a loop to achieve this. This loop has to loop 'the number of .test divs'/5 times:
$(document).ready(function () {
setTimeout(function () {
for (i=0; i<=$('.test').length/5; i++) {
$('.test').slice(5 * i, 5*(i+1)).delay(500*(i+1)).fadeIn(300);
};
}, 1000);
});
You can add a new method to jQuery like this:
$.fn.eachSlice = function(size, callback) {
var $t = $(this);
for(var i = 0; i < $t.length; i += size) {
callback.call($t.slice(i, i + size).get(), i / size);
}
return $t;
}
and then
$(".test").eachSlice(5, function(sliceIndex) {
$(this).delay(sliceIndex * 500).fadeIn();
});
http://jsfiddle.net/JT4KB/16/

Click counter, different events per click

I am seeking to create an array that counts and keep tracks of clicks done to a certain area of the page; I would then like each amount of click to do something. Eg.) The 5th click a sound via mp3 triggers. The sixth click the page shakes.
How could I write an array to add different events per a number of clicks, assigning something to a specific number of clicks?
var clicks = 0;
$('a').click(function() {
switch(++clicks) {
case X:
/* do something */
break;
/* ... */
}
});
Or you can store functions in array
var myEvents = [function1, function2, function3];
var clicks = -1;
$('a').click(function() {
clicks++;
if(myEvents[clicks] != undefined) myEvents[clicks]();
});
http://jsbin.com/izutav/1/edit
By simply creating an array of your events functions:
var a1_Events = [shake, noise, something],
a1_c = 0;
function shake(){
alert('SHAKING!');
}
function noise(){
alert('BZZZZZZZZZZZ!');
}
function something(){
alert('SOMETHING ELSE!');
}
$('#area1').click(function(){
a1_Events[a1_c++ % a1_Events.length]();
});
If you don't want to loop your events than use just: a1_Events[a1_c++]();
Something like this!
var actions = {
5: 'playMusic',
6: 'shakeDiv'
},
actors = {
doNothing: function() {/*default action; do nothing;*/},
playMusic: function() {
alert('Your are about to here a music now');
/*place code for playing music here*/
},
shakeDiv: function() {
alert('page is about to shake');
/* place shake animation code here*/
}
},
defaultActionName = 'doNothing';//default action name
var clickCount = 0;
$('yourSelectorForThepart').click(function(e) {
clickCount++;
doAction();
});
function doAction() {
var actionName = actions[clickCount] || defaultActionName;
actors[actionName]();
}
And yes, you could just merge actions & actors. But i prefer this approach for maintenance & readability.
You could do it like this:
// put your click actions as functions here
var clickEvents = [function1, function2, function3, function4, playMP3, shakePage];
var clicks = 0;
// put your clickable object here
clickableObject.onclick = function(){
clickEvents[clicks]();
clicks++;
}

JavaScript/jQuery clearInterval being set in .each

So I have an interval I create for each of my posts, the issue is that I load new posts and remove the old ones, so obviously I'd like to stop the interval for the previous posts. However I can't seem to figure out how to do this. Could someone explain to me how to properly go about doing this? I'm completely lost.
$(".post").each(function(){
myInterval = setInterval("postStats('"+$(this).attr('id')+"')", 500);
});
function postStats(pid) {
//do some stuff
}
$(".button").click(function(){
clearInterval(myInterval);
});
You can store the interval ID in a data attribute:
$(".post").each(function () {
var that = this;
var myInterval = setInterval(function () {
postStats(that.id);
}, 500);
$(this).data("i", myInterval);
});
and clear the interval specific to each .post like so:
$(".button").click(function () {
// assuming the button is inside a post
clearInterval($(this).closest(".post").data("i"));
});
and like SiGanteng said, you should pass a function object to setInterval rather than a string, which only gets eval'd.
You need to keep one handle for each interval that you start:
var myIntervals = [];
$(".post").each(function(){
var id = $(this).attr('id');
var handle = window.setInterval(function(){
postStats(id);
}, 500);
myIntervals.push(handle);
});
function postStats(pid) {
//do some stuff
}
$(".button").click(function(){
$.each(myIntervals, function(i, val){
window.clearInterval(val);
});
myIntervals = [];
});

Javascript "while hovered" loop

Can anybody help me on this one...I have a button which when is hovered, triggers an action. But I'd like it to repeat it for as long as the button is hovered.
I'd appreciate any solution, be it in jquery or pure javascript - here is how my code looks at this moment (in jquery):
var scrollingposition = 0;
$('#button').hover(function(){
++scrollingposition;
$('#object').css("right", scrollingposition);
});
Now how can i put this into some kind of while loop, so that #object is moving px by px for as #button is hovered, not just when the mouse enters it?
OK... another stab at the answer:
$('myselector').each(function () {
var hovered = false;
var loop = window.setInterval(function () {
if (hovered) {
// ...
}
}, 250);
$(this).hover(
function () {
hovered = true;
},
function () {
hovered = false;
}
);
});
The 250 means the task repeats every quarter of a second. You can decrease this number to make it faster or increase it to make it slower.
Nathan's answer is a good start, but you should also use window.clearInterval when the mouse leaves the element (mouseleave event) to cancel the repeated action which was set up using setInterval(), because this way the "loop" is running only when the mouse pointer enters the element (mouseover event).
Here is a sample code:
function doSomethingRepeatedly(){
// do this repeatedly when hovering the element
}
var intervalId;
$(document).ready(function () {
$('#myelement').hover(function () {
var intervalDelay = 10;
// call doSomethingRepeatedly() function repeatedly with 10ms delay between the function calls
intervalId = setInterval(doSomethingRepeatedly, intervalDelay);
}, function () {
// cancel calling doSomethingRepeatedly() function repeatedly
clearInterval(intervalId);
});
});
I created a sample code on jsFiddle which demonstrates how to scroll the background-image of an element left-to-right and then backwards on hover with the code shown above:
http://jsfiddle.net/Sk8erPeter/HLT3J/15/
If its an animation you can "stop" an animation half way through. So it looks like you're moving something to the left so you could do:
var maxScroll = 9999;
$('#button').hover(
function(){ $('#object').animate({ "right":maxScroll+"px" }, 10000); },
function(){ $('#object').stop(); } );
var buttonHovered = false;
$('#button').hover(function () {
buttonHovered = true;
while (buttonHovered) {
...
}
},
function () {
buttonHovered = false;
});
If you want to do this for multiple objects, it might be better to make it a bit more object oriented than a global variable though.
Edit:
Think the best way of dealing with multiple objects is to put it in an .each() block:
$('myselector').each(function () {
var hovered = false;
$(this).hover(function () {
hovered = true;
while (hovered) {
...
}
},
function () {
hovered = false;
});
});
Edit2:
Or you could do it by adding a class:
$('selector').hover(function () {
$(this).addClass('hovered');
while ($(this).hasClass('hovered')) {
...
}
}, function () {
$(this).removeClass('hovered');
});
var scrollingposition = 0;
$('#button').hover(function(){
var $this = $(this);
var $obj = $("#object");
while ( $this.is(":hover") ) {
scrollingposition += 1;
$obj.css("right", scrollingposition);
}
});

Categories