I am trying to have one div box act as a main button for multiple functions; and these functions would fire consecutively after each other; but per new CLICK. Eg, Click = Function fires. Click = next function in line fires, and so forth. Currently I have the below; which is fine, but it is not firing the functions consecutively as they are coded, per click as needed; one after another. Live demo of my dilemma at 'http://bit.ly/10BW89N'
So how to create one button and 30 functions that will be called on each click. If function is defined it will call the function otherwise it will alert the click number?
$(document).ready(function () {
var a1_Events = [function1, function2, function3, function4, function5, function6, function7, function8],
a1_c = 0;
function function1() {
alert('Click 1!');
}
function function2() {
alert('Click 2!');
}
function function3() {
$("#area1").hide();
$("#area2").show();
alert('Click 3!');
}
function function4() {
alert('Click 4!');
}
function function5() {
alert('Click 5!');
}
function function6() {
$("#bg_div").hide(0).delay(1500).show(0);
$("#bg_skew").show(0).delay(1500).hide(0);
alert('Click 6!');
}
function function7() {
alert('Click 7!');
}
function function8() {
$("#area1").hide(0).delay(1500).show(0);
$("#area2").hide(0).delay(1500).show(0);
$("#sound1").show(0).delay(4500).hide(0);
document.getElementById("id1").play();
$("#hammer").show(0).delay(1500).hide(0);
$("#youwin").show(0).delay(3500).hide(0);
alert('Click 8!');
}
$('#area1').click(function () {
a1_Events[a1_c++ % a1_Events.length]();
});
$("#area2").click(function () {
$("#area1").show();
$("#area2").hide();
alert('Click 9!');
});
});
function alert(msg) {
$("#alert").text(msg).show(0).delay(1500).hide(0);
}
You can simplify your code by using a switch or if statement based on the number of times the button/div has been clicked. Each case would control your actions, fire your functions, whatever...
$('button').click(function(){
++funcNum;
switch(funcNum){
case 1:
alert('This is click ' + funcNum);
break;
Here is an example fiddle - http://jsfiddle.net/juf5u/2
I would try this:
var a1_Events = [function1, function2, function3, function4, function5, function6, function7, function8];
$('#area1').click(function () {
if (a1_Events.length > 0)
{
var tfunc = a1_Events.shift();
tfunc();
}
else
{
// all functions have been executed
}
});
This code removes each function from the array as it is executed until it gets to the end. You will still need all the function declarations from the original code.
You could try this also:
$(document).ready(function () {
var a1_Events = function1,
a1_c = 0;
function function1() {
a1_Events=function2;
alert('Click 1!');
}
function function2() {
a1_Events=function3;
alert('Click 2!');
}
function function3() {
a1_Events=function4;
$("#area1").hide();
$("#area2").show();
alert('Click 3!');
}.... so on
Related
This function is needed for some time. But when tasks are completed I need to disable it, that after clicking on 'board' it wouldn't work.
board.addEventListener('click', event => {
if (event.target.classList.contains('circle')) {
score++
event.target.remove()
createRandomCircle()
} else if (!event.target.classList.contains('circle')) {
fault++
}
})
//Here I want to deactivate this event listener
I would call a handler function that returns a new named function (a closure) to act as the listener. You can then go through your tasks, and remove the listener when they're complete.
const board = document.querySelector('#board');
board.addEventListener('click', handler(), false);
function handler() {
// This is the function the listener uses
return function listener(e) {
console.log(e.target);
console.log('Task one');
console.log('Task two');
board.removeEventListener('click', listener);
console.log('The button no longer works.');
}
}
<button id="board">Board</button>
I have a animation that runs right before a stack of functions. I need the functions to run only after the animation is complete....a promise like behavior. I have a eventlistener for this. But the issue is, for efficiency I only want to have one event listener that all the page functions can use.
Is this possible to achieve with a single event listener? and how can I implement a promise like behavior when the event listener fires?
var mainPanelContent = document.getElementById('mainPanelContent');
mainPanelContent.addEventListener('webkitAnimationEnd', function (eve) {
console.log('anamation is done');
});
page('/', function (event) {
if (currentPage !== 0) {
//ON 'webkitAnimationEnd' do the below code
clickOnHome();
pageName = elementList[currentPage].localName;
toggleAllButActivePage(pageName);
findContentAndShow('home');
}
});
page('/portfolio', function () {
if (currentPage !=1) {
//ON 'webkitAnimationEnd' do the below code
toggleAllButActivePage('portfolio-page');
findContentAndShow('portfolio-page');
clickOnPage('rgb(68, 89, 99)');
}
});
page('/resume', function () {
if (currentPage !=2) {
//ON 'webkitAnimationEnd' do the below code
toggleAllButActivePage('resume-page');
findContentAndShow('resume-page');
clickOnPage('#424242');
});
Solution:
Thank you for your suggestions, I ended up going with this to keep the code lighter, otherwise I would have to remove the eventlistener after every promise wrap:
var afterSlideDown = { runStack: function() {} }
mainPanelContent.addEventListener('webkitAnimationEnd', function (animationEvent) {
if (animationEvent.animationName === "slide-down") {
afterSlideDown.runStack();
mainPanelContent.classList.remove('slide-down-now')
}
});
function portfolio() {
toggleAllButActivePage('portfolio-page');
findContentAndShow('portfolio-page');
clickOnPage('rgb(68, 89, 99)');
}
page('/portfolio', function () {
if (currentPage !=1) {
afterSlideDown.runStack = portfolio;
mainPanelContent.classList.add('slide-down-now');
}
});
Something like this should help?
var mainPanelContent = document.getElementById('mainPanelContent');
function addCustomEventListener()
{
return new Promise(function(resolve, reject){
mainPanelContent.addEventListener('webkitAnimationEnd', function (eve) {
resolve(true);
// you can come up with some logic to do a reject() ;-)
});
});
}
addCustomEventListener().then(function(){
// should be called when promise is resolved
console.log('anamation is done');
});
Event listener can work, it'd be just as if you were using callbacks. You can do this for a promise:
var p = new Promise(function(resolve){
function handler(e){
//just one time
mainPanelContent.removeEventListener('webkitAnimationEnd', handler);
resolve(e);
}
var mainPanelContent = document.getElementById('mainPanelContent');
//probs best to do animation here?
mainPanelContent.addEventListener('webkitAnimationEnd', handler);
});
p.then(function(e){
//animationEnded here:
//e = event data from the animationEnd handler.
});
I am playing around with a short little code to see if I can get a function going while the user has their mouse down and then end it when they bring their mouse up. For this example I am trying to increment a number that I am displaying on the screen as the user moves their mouse while holding the button down. I want it to freeze and stop once they release the button, however the counter just resets and the count continues from 0 even though the button is not being pressed...
function dragInit(state, e) {
var i = 0;
$(document).on("mousemove", function() {
if (state) {
i+=1;
$('#debug').text(i); //Show the value in a div
}
});
}
$(document).ready(function() {
$(document).on(
{mousedown: function(e) {
var state = true;
dragInit(e, state);
},
mouseup: function(e) {
var state = false;
dragInit(e, state);
}
});
});
As an aside, is there a way I can display whether a variable is true or false onscreen? When I try it just says [object Object].
There are a lot of mistakes in your code. I suggest you to read more basic concepts before starting to use jQuery.
The order of the parameters passed to dragInit() is wrong on both mouseup and mousedown event bindings.
The reason your counter is restarting is because your variable i is local, so it exists only during the function context it is declared in.
You are making the same mistake with the state variable, but in this case it is completely unnecessary to declare it.
Consider making your counter a global (even though it is not a good practice).
I can't provide you code because I am answering from my phone. A solution would be create a mousemove event that checkes whether the mouse button is pressed before incrementing your counter.
Hope I helped
You could do something like this:
function dragInit() {
$(document).on("mousemove", function () {
if (eventState.state) {
eventState.count += 1;
$('#debug').text(eventState.count); //Show the value in a div
}
});
}
// Create an object to track event variables
var eventState = {
count:0, //replaces your previous 'i' variable
state: false //keeps track of mouseup or mousedown
};
$(document).ready(function () {
$(document).on({
mousedown: function (e) {
eventState.state = true;
dragInit(); //don't need to pass anything anymore
},
mouseup: function (e) {
eventState.state = false;
dragInit(); //don't need to pass anything anymore
}
});
});
jsFiddle
Or keep everything together as one object
var dragInit = function () {
var count = 0;
var state = false;
var action = function () {
$(document).on("mousemove", function () {
if (state) {
count += 1;
$('#debug').text(count); //Show the value in a div
}
})
};
$(document).on({
mousedown: function (e) {
state = true;
action(); //don't need to pass anything anymore
},
mouseup: function (e) {
state = false;
action(); //don't need to pass anything anymore
}
});
}
$(document).ready(function () {
var obj = new dragInit();
});
jsFiddle 2
Example in response to comment
jsFiddle: This shows why the following code snippets differ in execution.
// Works
$(document).on("mousemove", function () {
if (state) {
}
})
// Doesn't
if (state) {
$(document).on("mousemove", function () {
});
}
Less code, You just need this.
Use jquery on and Off to turn on and off mousemove event.
Counter Reset http://jsfiddle.net/kRtEk/
$(document).ready(function () {
var i = 0;
$(document).on({
mousedown: function (e) {
$(document).on("mousemove", function () {
$('#debug').text(i++); //Show the value in a div
});
},
mouseup: function (e) {
i = 0;
$('#debug').text(i);
$(document).off("mousemove");
}
});
});
W/O Reset http://jsfiddle.net/gumwj/
$(document).ready(function () {
var i = 0;
$(document).on({
mousedown: function (e) {
$(document).on("mousemove", function () {
$('#debug').text(i++); //Show the value in a div
});
},
mouseup: function (e) {
$(document).off("mousemove");
}
});
});
WithNoCounter http://jsfiddle.net/F3ESx/
$(document).ready(function () {
$(document).on({
mousedown: function (e) {
$(document).on("mousemove", function () {
$('#debug').data('idx',parseInt($('#debug').data('idx')|0)+1).text($('#debug').data('idx')); //Show the value in a div
});
},
mouseup: function (e) {
$(document).off("mousemove");
}
});
});
Assuming you are married to Jquery (nothing wrong with that) - check out and consider entirely re-thinking your approach leveraging the ".one()" (http://api.jquery.com/one/) method.
edit: and if that taste doesn't sit well - familiarize yourself with the "deferred" object (http://api.jquery.com/category/deferred-object/)
lots of ways to approach this via jquery - what you decide in the end depends on what you really intend to do with this.
I have the following code. The first attempt at binding to click event does not work. The second way does. The first shows the alert "CheckBox1" during Page_Load. The second one shows the alert "CheckBox4" during the proper time -- during clicks.
$(document).ready(function () {
$(document.getElementById(checkBox1ID)).click( SetCheckBox1State(this.checked) );
$(document.getElementById(checkBox4ID)).click(function () { SetCheckBox4State(this.checked) });
});
function SetCheckBox1State(checked) {
alert("CheckBox2");
var radNumericTextBox1 = $find(radNumericTextBox1ID);
var wrapperElement = $get(radNumericTextBox1._wrapperElementID);
var label = $(wrapperElemenet.getElementsByTagName("label")[0]);
if (checked) {
radNumericTextBox1.enable();
label.addClass("LabelEnabled");
label.removeClass("LabelDisabled");
}
else {
radNumericTextBox1.disable();
label.addClass("LabelDisabled");
label.removeClass("LabelEnabled");
}
}
function SetCheckBox4State(checked) {
alert("CheckBox4");
var radNumericTextBox2 = $find(radNumericTextBox2ID);
var wrapperElement = $get(radNumericTextBox2._wrapperElementID);
var label = $(wrapperElemenet.getElementsByTagName("label")[0]);
if (checked) {
radNumericTextBox2.enable();
label.addClass("LabelEnabled");
label.removeClass("LabelDisabled");
}
else {
radNumericTextBox2.disable();
label.addClass("LabelDisabled");
label.removeClass("LabelEnabled");
}
}
Am I doing something improper? I'd rather not use an anonymous function...but maybe this just how things work?
This code:
.click( SetCheckBox1State(this.checked) );
Assigns the .click() function to be the output of this function: SetCheckBox1State(this.checked).
You will have to get rid of the argument (make it internal) and just pass the function name:
.click( SetCheckBox1State );
I am trying to write a javascript function that when called performs function DoSomething() once,
but can be triggered to perform the function repeatedly until triggered to stop.
I am using setTimeout() function. I am not sure if this is best method from performance and memory point of view.
Also I would like to avoid global variable if possible
<!DOCTYPE html>
<html>
<script src="jquery.js"></script>
<script>
var globalCheckInventory = false;
$(document).ready(function(){
// start checking inventory
globalCheckInventory = true;
myTimerFunction();
});
// check inventory at regular intervals, until condition is met in DoSomething
function myTimerFunction(){
DoSomething();
if (globalCheckInventory == true)
{
setTimeout(myTimerFunction, 5000);
}
}
// when condition is met stop checking inventory
function DoSomething() {
alert("got here 1 ");
var condition = 1;
var state = 2 ;
if (condition == state)
{
globalCheckInventory = false;
}
}
</script>
This is probably the easier way to do what you're describing:
$(function () {
var myChecker = setInterval(function () {
if (breakCondition) {
clearInterval(myChecker);
} else {
doSomething();
}
}, 500);
});
Another way to do it would be the store the timer ID and use setInterval and clearInterval
var timer = setInterval(DoSomething);
function DoSomething() {
if (condition)
clearInterval(timer);
}
I see nothing wrong with your implementation other than the pollution of the global namespace. You can use a closure (self-executing function) to limit the scope of your variables like this:
(function(){
var checkInventory = false, inventoryTimer;
function myTimerFunction() { /* ... */ }
function doSomething() { /* ... */ }
$(document).ready(function(){
checkInventory = true;
/* save handle to timer so you can cancel or reset the timer if necessary */
inventoryTimer = setTimeout(myTimerFunction, 5000);
});
})();
Encapsulate it:
function caller(delegate, persist){
delegate();
if(persist){
var timer = setInterval(delegate, 300);
return {
kill: function(){
clearInterval(timer);
}
}
}
}
var foo = function(){
console.log('foo');
}
var _caller = caller(foo, true);
//to stop: _caller.kill()