If I create a button with the name "Level 0" and onmousedown I have it run learnSkill(3) it only increments the skill[3].Value to 1, then it picks up a click but does nothing, why?
I am trying to code a skill tree, I haven't gotten very far because of issues like this so it's mostly empty.
var skill = new Array();
function Skill(value, name, type, tier, column, info, requirement) {
this.Value = value;
this.Name = name;
this.Type = type;
this.Tier = tier;
this.Column = column;
this.Info = info;
this.Req = requirement;
//skill[id].Req
}
function SkillReq(id, amount, reqby) {
this.Id = id;
this.Amount = amount;
this.By = reqby;
//skill[id].Req.Id
//skill[id].Req.Amount
//skill[id].Req.By
}
skill[1] = new Skill(0, "Unholy Sphere", "Tree 2", 0, 1, new Array(), new SkillReq(0, 0, 3));
skill[3] = new Skill(0, "Dark Circle", "Tree 2", 1, 0, new Array(), new SkillReq(1, 3, 0));
function canLearn(id) {
alert("in canlearn");
canLearn = true;
return canLearn;
}
function canUnlearn(id) {
}
function learnSkill(id) {
alert("id: "+id);
if (!canLearn(id)) {
alert("cannot learn");
return;
}
// Increase current skill value
skill[id].Value++;
alert(skill[id].Value);
// totalSP--; Decrease totalSP, must declare first
// Update button to show new level of skill value
document.getElementById(id).value = "Level "+skill[id].Value;
}
function unlearnSkill(id) {
if (!canUnlearn(id)) {
return;
}
}
function onClickTalent(id) {
}
function rmbDown(e)
{
var isRMB = false;
e = e || window.event;
if (e.which)
isRMB = (e.which == 3);
else if (e.button)
isRMB = (e.button == 2);
return isRMB;
}
You are overwriting your canLearn function inside of it, the canLearn identifier you assign to true is the function itself, to create a new variable in the function scope use the var keyword
function canLearn(id) {
alert("in canlearn");
var canLearn = true;
return canLearn;
}
I'm not really sure what it is you're trying to do, but here's one problem:
function canLearn(id) {
alert("in canlearn");
canLearn = true;
return canLearn;
}
That function will "self-descruct" the first time it's called, because you're setting the global symbol "canLearn" to true. Trouble is, "canLearn" is already used - as the name of that function! Thus, subsequent attempts to call "canLearn" will fail because its value is no longer a function object.
Related
I want to have 2 buttons. Button A when clicked appends to Array A. Button B > Array B.
var names = ['Hannah', 'Lucy', 'Brenda', 'Lauren', 'Mary'];
<button id="likebutton" type="button">Like</button>
<button id="dislikebutton" type="button">Dislike</button>
function likeOrDislike(){
var off = true;
document.getElementById('likeButton').onClick = function(){
var off = false;
}
document.getElementById('dislikeButton').onClick = function(){
var off = true;
}
if(off = false) {
liked.push(names[0])
names.splice(0, 1)
}
else if (off = true) {
disliked.push(names[0])
names.splice(0, 1)
}
};
Then I call the function in this while loop:
while(names.length > 0){
document.getElementById('demo').innerHTML = names[0];
likeOrDislike()
};
Im sure there is a better way to do this then that horrible off variable.
I am getting this error at the moment
tinder.html:25 Uncaught TypeError: Cannot set property 'onClick' of null
Use .addEventListener('click', callback) or .onclick instead of .onClick
To compare values use double == or triple equals ===
Don't use while in such context. Function will be looping all the time!
Read more about Javascript, for example on w3schools
I've created working jsFiddle for you.
Here is the code:
var names = ['Hannah', 'Lucy', 'Brenda', 'Lauren', 'Mary'],
liked = [],
disliked = [];
showName();
document.getElementById('likeButton').onclick = like;
document.getElementById('dislikeButton').onclick = dislike;
function showName(){
var name = names[0];
if(!name){
name = "The End";
}
document.getElementById('demo').innerHTML = name;
}
function like(){
liked.push(names[0]);
names.splice(0, 1);
showName();
}
function dislike(){
disliked.push(names[0]);
names.splice(0, 1);
showName();
}
I am making a minecraftpe mod and I have to access the value of something which is set in another (because using setTile in java functions crashes the game as x, y, z are only defined in the useItem template.) So I needed to do this basically here is the function I am using...
var ctx = com.mojang.minecraftpe.MainActivity.currentMainActivity.get();
var seekerProgress = 0;
function newLevel()
{
run: function()
{
try
{
var modWindow = new android.widget.PopupWindow();
var modLayout = new android.widget.LinearLayout(ctx);
var seeker = new android.widget.SeekBar(ctx);
seeker.setProgress(seekerProgress);
seeker.setMax(1);
modLayout.addView(seeker);
modWindow.setContentView(modLayout);
modWindow.setHeight(android.widget.LinearLayout.LayoutParams.WRAP_CONTENT);
modWindow.setWidth(android.widget.LinearLayout.LayoutParams.WRAP_CONTENT);
modWindow.showAtLocation(ctx.getWindow().getDecorView(), android.view.Gravity.CENTER | android.view.Gravity.CENTER, 0, 0);
seeker.setOnSeekBarChangeListener(new android.widget.SeekBar.OnSeekBarChangeListener() {
onStopTrackingTouch: function()
{
seekerProgress = seeker.getProgress();
if (seekerProgress === 1)
{
print(target);
}
}
});
}
}
}
function modFunction()
{
var target = 0; //I want this value to be accessible in the newLevel function
}
What can I do to aide this?
I'm trying to remove JQuery from a project I inherited and I have stumbled upon this line of code which doesn't really make sense.
$.each(options.reservationOptions,this._addToSelect, [select]);
What does $.each() do when there are 3 things passed to it.
The first is an object, the second is a function, and the third is a var.
Here is the [select] init:
var select = L.DomUtil.create('select', 'booking-select ' + options.RoomName, reservationContainer);
Here is the function:
_addToSelect: function (select) {
try {
var value = this.value;
var text = this.text;
if (text) {
var option = $("<option>").addClass('booking-option').text(text);
//var option = L.DomUtil.create('option', 'booking-option');
//option.innerText = text;
if ( value )
option.val(value);
//option.value = value;
option.appendTo(select);
//select.appendChild(option.get());
//var optionsList = select.options || select;
//optionsList.add(option.get());
}
} catch (ex) {
console.log('could not add option to select ' + ex.message);
}
It iterates, the first argument is the array or object, the second is the callback, and the third is the arguments passed in to the callback. In a loop you'd do the same thing with (assuming array)
options.reservationOptions.forEach(function(item) {
this._addToSelect.apply(item, [select]);
}.bind(this));
Here's a short version of what jQuery does
$.each = function (obj, callback, args) {
var value,
i = 0,
length = obj.length,
isArray = isArraylike(obj);
if (args) {
if (isArray) {
for (; i < length; i++) {
value = callback.apply(obj[i], args);
if (value === false) {
break;
}
}
} else {
for (i in obj) {
value = callback.apply(obj[i], args);
if (value === false) {
break;
}
}
}
}
}
forEach takes 2 arguments, callback and context – https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Array/forEach
options.reservationOptions.forEach(function(option) {
this.options.reservationOptions(option);
}, this);
So I am using a function to update my values, but I can't then get them back. I see values don't get updated, but is there any way of saving them as a reference to the return of the function.
function Amphibia(wheelRadius, finsPerPropeller, propellersSpinDirection, mode) {
this.speed = 0;
this.mode = mode;
var amphibiaWheel = new PropulsionUnits.Wheel(wheelRadius);
var amphibiaPropeller = new PropulsionUnits.Propeller(finsPerPropeller, propellersSpinDirection);
this.changeMode = function () {
if (mode == "land") {
mode = "water";
}
else if(mode == "water") {
mode = "land";
}
return {
mode: mode
}
}
this.accelerate = function() {
if(this.mode == "water"){
this.speed += amphibiaPropeller.acceleration;
}
else if(this.mode == "land"){
this.speed += 4*amphibiaWheel.acceleration;
}
}
this.changePropellerSpinDirection = function() {
amphibiaPropeller.changeSpinDirection();
}
return {
speed: this.speed,
mode: this.mode,
changeMode: this.changeMode,
accelerate: this.accelerate,
changePropellerSpinDirection: this.changePropellerSpinDirection
}
}
So here I am experiencing problems with changing the mode and the changeMode function expression. Mode in it should refer to this.mode and then I should be able to update the value.
mode and this.mode are not the same. In your functions you are checking/setting values on mode and this.mode, separately.
Either should work fine, as long as you're using one or the other, in the same place, the same way.
Edit
var Amphibia = function (wheelRadius, finsPerPropeller, propellersSpinDirection, mode) {
var amphibia = this,
MODES = { LAND : "land", WATER : "water" };
amphibia.getMode = function () { return mode; };
amphibia.setMode = function (val) { mode = val; };
amphibia.changeMode = function () {
amphibia.setMode((mode === MODES.LAND) ? MODES.WATER : MODES.LAND);
};
};
var amphibia = new Amphibia("", "", "", "land");
amphibia.getMode(); // "land"
amphibia.changeMode();
amphibia.getMode(); // "water"
mode is now 100% private, and unique to that instance.
If you don't need it to be, then you can append it to this, if you'd like.
But here's your problem:
var Amphibia = function () {
var amphibia = this,
amphibiaPropeller = new Propeller( );
// mode, getMode, setMode, etc...
amphibia.accelerate = function () {
if (amphibia.getMode() === "water") {
this.speed += amphibiaPropeller.acceleration;
}
};
};
var amphibia = new Amphibia();
var bob = { speed : 0 };
bob.accelerate = amphibia.accelerate;
bob.accelerate();
// if amphibia.mode === "water", bob.speed += amphibiaPropeller.acceleration
bob.speed; // === amphibiaPropeller.acceleration
setTimeout(amphibia.accelerate, 10); // call amphibia.accelerate in ~10ms
// if amphibia.mode === "water", window.speed += amphibiaPropeller.acceleration
window.speed; // === amphibiaPropeller.acceleration
Be consistent in how you refer to things.
Don't mix self and this, unless you intend to get those side-effects...
And unless you have a very, very good reason to do so (like you're building a framework/engine, not the modules/classes of the game/simulation which use the engine; ie: the difference between building jQuery and building something with jQuery), then you should probably avoid doing it.
If you have closure ("private") state that you want to expose to the outside world, all you need is a function that returns that value, and/or one that sets it.
All of a sudden, the differences between self and this and what is which, when, all go away, as long as you are consistent with how you use them, and you know what the value of this is going to be, every time you call the method.
Notice I'm not returning anything...
When I use new, the value of this (amphibia/self) gets returned by default.
If you want to use private values, and return a "Revealing Module" (which is what I typically prefer), then you can simply do this:
var Amphibia = function (mode) {
var getMode = function () { return mode; },
setMode = function (val) { mode = val; },
changeMode = function () {
setMode( mode === "water" ? "land" : "water" );
};
return {
getMode : getMode,
setMode : setMode,
changeMode : changeMode
};
};
var amphibia = new Amphibia("water");
// `new` won't do any harm, but you can also not use it,
// without it saving everything to `window`
amphibia.getMode(); // "water"
amphibia.changeMode();
amphibia.getMode(); // "land"
Or, maybe if you want that to look a little more like a module/component...
return {
mode : { get : getMode, set : setMode, switch : changeMode }
};
var amphibia = Amphibia("land");
amphibia.mode.get(); // "land"
amphibia.mode.switch();
amphibia.mode.get(); // "water"
var bob = { };
bob.switchAmphibiaMode = amphibia.mode.switch;
bob.switchAmphibiaMode();
amphibia.mode.get(); // "land"
setTimeout(amphibia.mode.switch, 10);
setTimeout(function () { console.log(amphibia.mode.get()); }, 20);
// 10ms amphibia.mode.switch();
// 20ms console.log(amphibia.mode.get());
// > "water"
...or whatever other structure you'd like.
You don't need a this at all.
But this is something to be very, very careful with in JavaScript, because the meaning of this changes every time you call a function, and if half of the code uses this and half uses self, you're bound for some surprises.
I managed to find the answer myself! :) So basicly this in the function constructor refers to Amphibia and this in the this.changeMode function expression refers to object window. Therefore we can define a variable self = this; in the constructor, so we can refer to the same thing in the function expression, as in the function. I explained it a bit awful, but here is my fixed code ;)
function Amphibia(wheelRadius, finsPerPropeller, propellersSpinDirection, mode) {
this.speed = 0;
var self = this;
self.mode = mode;
var amphibiaWheel = new PropulsionUnits.Wheel(wheelRadius);
var amphibiaPropeller = new PropulsionUnits.Propeller(finsPerPropeller, propellersSpinDirection);
this.changeMode = function () {
if (self.mode == "land") {
self.mode = "water";
}
else if(self.mode == "water") {
self.mode = "land";
}
}
this.accelerate = function() {
if(self.mode == "water"){
this.speed += amphibiaPropeller.acceleration;
}
else if(self.mode == "land"){
this.speed += 4*amphibiaWheel.acceleration;
}
}
this.changePropellerSpinDirection = function() {
amphibiaPropeller.changeSpinDirection();
}
return {
speed: this.speed,
mode: this.mode,
changeMode: self.changeMode,
accelerate: this.accelerate,
changePropellerSpinDirection: this.changePropellerSpinDirection
}
}
I am trying to pass a variable to a a function that I believe calls another function (I think) but am having problems. The variable I need to use in the second function is productid but several ways thAt I have tried have not worked. either a fix in javascript or Jquery will be great!!!
This is the line that I need the variable for
var error_url = '/ProductDetails.asp?ProductCode' + productid;
this is where the variable originates from...
var productid = form.elements['ProductCode'].value;
and here is the whole js code
function addToCart2(form, button) {
var softAdd = true;
var productid = form.elements['ProductCode'].value;
var qstr;
var bttnName = button.name;
button.disabled = true;
if (form.elements['ReturnTo']) {
form.elements['ReturnTo'].value = "";
}
qstr = serialize(form, bttnName + '.x', '5', bttnName + '.y', '5');
sendAjax('POST','/ProductDetails.asp?ProductCode=' + productid + '&AjaxError=Y', qstr , retrieveProductError2 ,displayServerError,false);
button.disabled = false;
return false;
}
function retrieveProductError2(result, statusCode) {
var ele = document.getElementById('listOfErrorsSpan');
var errorIndex = result.indexOf('<carterror>');
var productIndex = result.indexOf('<ProductIndex>')
if (errorIndex > -1 && productIndex == -1) {
var error_url = '/ProductDetails.asp?ProductCode' + productid;
window.location = error_url;
}
if (errorIndex != -1) {
//ele.innerHTML = result.slice(errorIndex + 11, result.indexOf('</carterror>'));
}
else {
ele.innerHTML = "";
if (productIndex == -1) {
sendAjax('GET','/AjaxCart.asp?GetIndex=True', '', showCart, null, false);
}
else {
productIndex = result.slice(productIndex + 14, result.indexOf('</ProductIndex>'));
sendAjax('GET','/AjaxCart.asp?Index=' + productIndex, '', showCart, null, false);
}
}
}
The easiest way is to just move your variable declaration outside of your method. So change the declaration of product id outside your addToCart2 method. So outside of that method you do this:
var product_id;
Then inside your method remove var from product_id and it will just be an assignment and not declaration.
Where you pass in retrieveProductError2 as your error callback for the sendAjax call, you could instead pass in:
function(result, statusCode) { retreiveProductError2(result, statusCode, productId);}
Then change the definition of your retreiveProductError2 function to accept the additional parameter.