JavaScript - from alert to function - javascript

I'm very new on my quest for learning JavaScript(only two weeks) so be nice and surprised how far I got.
What I’m trying to do is hit a button and the button will evoke a random image or div to come to the front. I as you see I use the z-index by moving elements from back to front.
I have got far enough to create an alert that tells me it does find the random function just cant get it to activate this function (the changeCombined functions do work fine when I assign it to a button but just can’t get the getImage to run).
I’m unsure if it is possible, and I know there might be a hundred better ways to do this but one step at a time.
function changeZIndex(i,id) {
document.getElementById(id).style.zIndex=i;
};
var changeCombined1 = function() {
changeZIndex(-5,"scene1");
changeZIndex(5,"scene2");
};
var changeCombined2 = function() {
changeZIndex(-5,"scene2");
changeZIndex(5,"scene1");
};
function get_random(){
var ranNum= Math.floor(Math.random()*2);
return ranNum;
}
function getImage(){
var whichImage=get_random();
var image=new Array()
image[0]=changeCombined2;
image[1]=changeCombined1;
alert(quote[whichImage]);
}

Try this:
function changeZIndex(i,id) {
document.getElementById(id).style.zIndex=i;
};
function getImage(){
var whichImage=Math.floor(Math.random()*2);
var image=new Array()
image[0]=function() {
changeZIndex(-5,"scene2");
changeZIndex(5,"scene1");
};
image[1]=function() {
changeZIndex(-5,"scene1");
changeZIndex(5,"scene2");
};
image[whichimage]();
alert(quote[whichImage]);
}

To invoke a function you should use either apply or call methods.
Have you tried image[whichImage].apply(undefined) instead of your alert ?

You are not calling the changeCombined() functions at all.
If you are trying to call the functions, you have to use ()
image[0]=changeCombined2();
image[1]=changeCombined1();
What you have just the functions themselves to image[0] and image[1].
So after
x = changeCombined2;
x will hold a reference to the changeCombined2 function itself. So now if you say x() (or in your case image[0]()), it will call changeCombined2.
() will call the functions and will put the return value of the function into the array elements.
Note: since the functions do not explicitly return anything, image[0] and image[1] will hold undefined.

Thanks for all the help to get past my road block, the rookie mistake of not calling my funcions was the biggest issue. I was able montage the comments to create this version that works as expected.
function changeZIndex(i,id) {
document.getElementById(id).style.zIndex=i;};
function getImage(){
var whichImage=Math.floor(Math.random()*2);
var image=new Array()
image[0]=function() {
changeZIndex(-5,"scene2");
changeZIndex(5,"scene1");
};
image[1]=function() {
changeZIndex(-5,"scene1");
changeZIndex(5,"scene2");
};
image[whichImage].apply(undefined);};

Related

JavaScript function not executing at all

The code isn't doing anything at all, the images are just staying still
Here's the code, I commented where the function that isn't running is
If the question is too vague ask me for details, I don't know how to explain this more simple than it already is
var Car=function(x,y) {
this.x=x;
this.y=y;
};
Car.prototype.draw=function() {
var carHtml='<img src="http://nostarch.com/images/car.png">';
this.carElement=$(carHtml);
this.carElement.css({
position:"absolute",
left:this.x,
top:this.y,
});
$("body").append(this.carElement);
};
Car.prototype.moveRight=function() { // Function that isn't working
this.x+=5;
this.carElement.css({
left:this.x,
top:this.y
});
};
var tesla=new Car(20,20);
var nissan=new Car(100,200);
tesla.draw();
nissan.draw();
var ID=setInterval(nissan.moveRight(),1500);
The issue seems to be with this line
var ID=setInterval(nissan.moveRight(),1500);
The first argument of setInterval is a function or a callback function. So you either need to pass only nissan.moveRight or put it inside a function
var ID=setInterval(function(){nissan.moveRight()},2500);
JSFIDDLE

Avoid Jquery self calling function

I got below a Jquery function to switch between two buttons simultaneously but it's a "dirty" way of writing the code my boss will say. I don't wanna call the functions or no passing in Jquery parameter, is the there a simple or better way to write this function since i'm totally new to programming?
Below the Jquery
var startStopBtn = function () {
var startBtn = $('#timerStart');
var stopBtn = $('#timerStop').hide();
var Start = function () {
startBtn.hide();
stopBtn.show();
};
var Stop = function () {
var remarks2 = $(".textArea-one").val();
if (remarks2 !== "") {
startBtn.show();
stopBtn.hide();
}
};
return {
Start: Start,
Stop: Stop
};
}(jQuery);
jQuery('#timerStart').on('click', startStopBtn.Start);
jQuery('#timerStop').on('click', startStopBtn.Stop);
I think code could be done in many ways, this is just one of them.
Looks like first you want to hide the stopBtn so create a function to do this. Call that function on page load or create a funtion and call it when the page loads. Here I create a function that you should call whenever you want. If you don't want to do that, just delete that function.
Then make two diferent functions that are done when you "click" #timerStart or #timerStop.
This is my version but i'm sure it can be improved:
function startStopBtn(){
$('#timerStop').hide();
};
$('#timerStart').on('click', function(){
$('#timerStart').hide();
$('#timerStop').show();
});
$('#timerStop').on('click', function(){
var remarks2 = $(".textArea-one").val();
if (remarks2 !== "") {
$('#timerStart').show();
$('#timerStop').hide();
}
});

Javascript: uncaught typeerror undefined is not a function for object methods

I make a simple quiz game. Here is some relevan methods that i have inside one object.
But doesn't work. I always get an error within 'rightAnswerGot' function. Console drops
"uncaught typeerror undefined is not a function for object methods" for this.addVariantsHtml(this.updateCharacter());
BasicGame.Game.prototype = {
actionOnClick: function (button) {
var log;
if(button.value==this.char_bubble.text) {
setTimeout(this.rightAnswerGot,1000);
} else {
// wrong
swoshsound.play();
}
console.log(log);
},
rightAnswerGot: function (){
this.addVariantsHtml(this.updateCharacter());
},
addVariantsHtml: function(id) {
this.answer = this.getAnswersVariants(id);
for (var i = 0; i < 6; i++) {
this.button[i].value = this.answer[i]['trans'];
this.button[i].char_id = this.answer[i]['id'];
this.ans_text[i].setText(this.answer[i]['trans']);
}
},
updateCharacter: function() {
var i = this.getRandomCharacter();
console.log("updateCharacter: "+i + " " +this.chars[i]);
this.char_bubble.setText(this.chars[i].getPath());
return i;
}
}
The aim is to froze the game for a second, when user choose the right answer, and than go to next question. Any ideas why does it happens?
Thanks
Looks like a classic JavaScript scope issue to me. However as you've tagged this question as using Phaser, I would suggest you use a Phaser Timer event to avoid scope problems. Specifically:
setTimeout(this.rightAnswerGot,1000);
replace it with:
this.game.time.events.add(Phaser.Timer.SECOND, this.rightAnswerGot, this);
Which will create a single 1 second timer that fires only once, calling your function at the end of it. You can use 1000 instead of Phaser.Timer.SECOND of course.
I would image that whats happening is that its trying to call the this.addVariantsHtml method, before its calling this.updateCharacter and getting the ID.
So your probably expecting that when it runs, for it to be something like:
this.addVariantsHtml(1);
But its actually trying to run
this.addVariantsHtml(this.updateCharacter());
So just do this:
var id = this.updateCharacter();
this.addVariantsHtml(id);
Either that or you need to look into method chaining/piping, which is just complicated and doesnt need to be used for this situation, but is interesting :)
Ok I found something that made it work!!
Here is a solution:
actionOnClick: function (button) {
var log;
if(button.value==this.char_bubble.text) {
var context=this;
setTimeout(function() {
context.addVariantsHtml(context.updateCharacter());
},1000);
} else {
// wrong
swoshsound.play();
}
console.log(log);
},

Calling functions in two different ways - JavaScript

I'm very new to JavaScript, so my apologies if this answer is glaringly obvious or I'm barking up the wrong tree!
What's the difference in the following code snippets:
function primeAddNum(innerHTML) {
return function() {
addNum(innerHTML);
return false;
};
}
var func = primeAddNum(innerHTML);
The second one:
var func = function() {
return function() {
addNum(innerHTML);
return false;
};
}();
The top one works the way I'd like it to, but not the bottom, but that's not overly important to me. What I want to know is the logic behind each block, because I just can't see the difference!
The problem with the second block is that innerHTML is undefined there, since you're not passing it. They will become equivalent if you change it to:
var func = function(innerHTML) {
return function() {
addNum(innerHTML);
return false;
};
}(innerHTML);
Well with the second one you can only create a func once. But with first one, you can create many:
var func1 = primeAddNum(innerHTML);
var func2 = primeAddNum(someOtherInnerHTML);
there is no difference, you can use both without any problems

Confused by this - getting error "this.myfuntion() is not a function"

Background: I am trying to edit a zen cart horizontal pop out menu to make the popout open inline within the menu. The problem I am having is that I am struggling to get my head around the javascript/jquery that came with it.
Without posting the whole thing the structure of the code is something like this:
(declare some vars)
//some functions like this:
function funcname(obj) {
//do something
}
//then one big master function like this:
function bigfunc(arg1, arg2, arg3, arg4, arg5) {
//declare some vars based on this
this.varname1=varname1;
this.varname2=varname2;
//declare some functions inside the big function
this.innerfunc1= function() {
//do stuff
}
this.innerfunc2= function() {
//do stuff
}
}//end of big function
//then goes on to declare init function
function initfunc(){
//this creates new bigfunc(arg1 arg2 arg3...) for each main menu item
}
//finally calls init function with
window.onload = initfunc();
Now on to my confusion -
1) firstly for clarification, am I correct in thinking based on all the this's floating about in bigfunc() and the fact that it is called with new bigfunc() that this is creating an object?
2)My current problem is with one of the functions inside bigfunc() which looks like this:
this.slideChildMenu = function() {
var divref = this.children[0].div;
var ulref = this.children[0].ul;
var maxwidth = this.children[0].width;
var nextWidth;
if (this.isMouseOnMe || this.isMouseOnChild()) {
nextWidth = divref.offsetWidth + slideSpeed_out;
if (nextWidth >= maxwidth) {
this.finishOpeningChild(divref, ulref, maxwidth);
} else {
ulref.style.left = nextWidth - maxwidth + "px";
divref.style.width = nextWidth + "px";
setTimeout("slideChildMenu('" + this.getId() + "')", slideTimeout_out);
}
}
Now my plan is to alter this to use jquery show to open the element so I tried this:
this.slideChildMenu = function() {
var divref = this.children[0].div;
var ulref = this.children[0].ul;
if (this.isMouseOnMe || this.isMouseOnChild()) {
$(divref).show(function(){
this.finishOpeningChild(divref, ulref);
});
}
}
But I am getting this-> TypeError: this.finishOpeningChild is not a function
Now, there is a lot of other stuff going on in this js so I wouldnt dream of asking someone on here to do my work for me, but I am hoping that if someone can explain to me why this function is not a function I may be able to work the rest out.
NOTE: I thought this was to do with the scope of "this" but the value of this appears to be exactly the same in both versions of the code.
I know this is a long one but your help is greatly appreciated.
The value of this in a function is called the "context" in which the function runs. In general, whenever you pass a callback function as an argument (as you do with $(divref).show(function() {...})), the function can run the callback in whatever context it wants. In this case, the jQuery show function chooses to run its callback in the context of the element being animated.
However, you want access to the value of this at the time the anonymous callback function is defined, rather than when it is run. The solution here is to store the outer value of this in a variable (traditionally called self) which is included in the scope of the newly-defined function:
this.slideChildMenu = function() {
//...
var self = this;
$(divref).show(function(){
self.finishOpeningChild(divref, ulref);
});
}
I am thinking that the jQuery selector has changed the scope of this.
In your example $(this); would refer to object being animated per jQuery api docs:
If supplied, the callback is fired once the animation is complete. This can be useful for stringing different animations together in sequence. The callback is not sent any arguments, but this is set to the DOM element being animated. If multiple elements are animated, it is important to note that the callback is executed once per matched element, not once for the animation as a whole.
If the object in question is instantiated you can call it with dot notation without using this like bigFunc.finishOpeningChild(divref, ulref);
You're probably a little confused about scope, it's not always easy keeping track, but doing something more like this:
var site = {
init: function(elm) {
self=site;
self.master.funcname2(self.varname1, elm); //call function in master
},
funcname: function(obj) {
//do something
},
varname1: 'some string',
varname2: 3+4,
master: function() {
this.varname3 = sin(30);
this.funcname2 = function(stuff, element) {
site.funcname(element); //call function in 'site'
var sinus = site.master.varname3; //get variable
}
}
}
window.onload = function() {
var elm = document.getElementById('elementID');
site.init(elm); //call init function
}
usually makes it a little easier to keep track.

Categories

Resources