How to create a simple variable alternator triggered by onclick? - javascript

This seems like a simple thing, my problem is that I learn things randomly, not in order.
I'm after a simple cycling/alternator where pushing something switches from one state to another eg. 1,2,1,2,1,etc...
So
I have my object to be clicked
<div onclick="alternateVar();">Click me</div>
Then I have the function/variable declaration/properties
I am not sure which variable setup I should choose I have shown three cases.
<script>
// check current value of variable
alert(mode);
// variable declaration
var mode = {value=1}; // method one
var mode = new Number(); // method two
var mode = 1; // method three
// alternate variable
function alternateVar() {
// attempt 1
if(mode.value == 1){
mode.value(2); // set new value to variable
}else {
mode.value(1);
}
// attempt 2
if(mode.value == 1){
var mode = 2; // overwrite? is it global?
}else {
var mode = 1;
}
}
</script>

Here's my fiddle. I just used a ternary operator! Is this what you needed?
var number = 1;
var button = document.getElementById("button");
button.onclick = alternateVar;
function alternateVar() {
number = number == 1 ? 2 : 1;
alert(number);
}

Related

Variable Set to undefined

I am fairly new to Javascript and i ran into a problem when creating a chess game . I have already made the board, but when i tried incorporating JS code that would move these peices when i clicked on them, a problem arose. See i declared the variable "x" to hold the value of the chess peice value that had been clicked on when count=0 but when i tried it out, the code just outputs x as 'undefined'.What have i done wrong, any help would be appreciated :)
(below is a snippet of my JS code)
<div onclick="changeText(63)"id="63"class="black">♘</div>
<div onclick="changeText(64)"id="64"class="white">♖</div>
</div>
<script>
var count = 0;
var x;
function changeText(id) {
if (count > 1){
count = 0;
}
if(count=0){
x = document.getElementById(id).innerHTML;
document.getElementbyId(id).innerHTML="";
}
if(count=1){
document.getElementById(id).innerHTML=x;
}
count = count + 1;
}
</script>
The second and third if statements will not be evaluating the variable value - because rather than comparison (count=== 0) what happens there is a variable assignment (count = 0).
The if (count = 0) is evaluated to false, so, the variable x never gets a value.
On the other hand if (count = 1) is evaluated to true. So, the HTML element gets an undefined string. Your code should look like this:
...
if (count === 0){
x = document.getElementById(id).innerHTML;
document.getElementbyId(id).innerHTML="";
}
if( count === 1){
document.getElementById(id).innerHTML=x;
}
Reference: https://www.w3schools.com/js/js_comparisons.asp
You don't need to pass the id to that handler function if it's doing the same thing. If you want a function that changes the innerHTML of the thing that was clicked, try passing event to the handler, and then using event.target.innerHTML like this:
<div onclick="changeText(event)" class="black">♘</div>
<div onclick="changeText(event)" class="white">♖</div>
<script>
function changeText(event) {
if (event.target.innerHTML === 'x') {
event.target.innerHTML = 'y' // you can do anything here
} else {
event.target.innerHTML = 'x'
}
}
</script>

Javascript if statement in function overwriting global variable?

Am attempting to create a static navigation panel which becomes absolute at the bottom before the footer when reaching the end of the page content.
As I am developing for wordpress the page could be of varying height so I have attempted to trigger the absolute positioning when the nav panel “collides” with the footer.
So far I have used this code I found here
function collision($archive, $footer){
var archivexPos = $archive.offset().left;
var archiveyPos = $archive.offset().top;
var archiveHeight = $archive.outerHeight(true);
var archiveWidth = $archive.outerWidth(true);
var archiveb = archiveyPos + archiveHeight;
var archiver = archivexPos + archiveWidth;
var footerxPos = $footer.offset().left;
var footeryPos = $footer.offset().top;
var footerHeight = $footer.outerHeight(true);
var footerWidth = $footer.outerWidth(true);
var footerb = footeryPos + footerHeight;
var footerr = footerxPos + footerWidth;
if (archiveb < footeryPos || archiveyPos > footerb || archiver < footerxPos || archivexPos > footer) return Boolean = false;
return Boolean = true;
And used a global variable of Boolean to pass to this function
$(window).on('scroll', function() {
var scrollmath = Math.round($(window).scrollTop());
var archiveValue = scrollmath + 48;
var archiveBottom = archiveValue + 'px';
console.log('collision boolean', Boolean)
if (Boolean = false) {
$('#archive').css('position', 'fixed');
$('#archive').css('top', '48px');
} else {
$('#archive').css('position', 'absolute');
$('#archive').css('top', archiveBottom);
}
My problem is the if statement seems to be creating another Boolean variable? As when I comment it out I can see that the console reports the Boolean variable as expected. However when I leave it in and they collide this happens
Whats happened here?
The primary thing that's happening is that you're using = for comparison. JavaScript uses == (or ===), not =. = is always assignment.
But when testing the value of a boolean, you don't want == or != anyway, just use the boolean directly:
if (flag) {
// It was true
} else {
// It was false
}
Or if you're just testing for false:
if (!flag) {
// flag was false
}
(Note that because JavaScript does type coercion, that will also work with variables containing values other than booleans: Any truthy value coerces to true, any falsy value coerces to false. The falsy values are 0, "", NaN, null, undefined, and of course, false; all other values are truthy.)
Separately: Boolean is not a good choice for a variable name, as it's part of the JavaScript standard library (a function).
Also, your current collision function does two things:
It sets Boolean to true or false
It returns the value it set
In general, all other things being equal, it's best if a function doesn't have side-effects like that. If the caller wants to set Boolean to the return value of the function, he/she can, there's no need for the function to do it — it's already returning the value.
And finally: Global variables are, in general something to avoid. The global namespace on browsers is incredibly crowded and it's easy to get conflicts (for instance, a global called name may well not work as expected, because there's already a name global [it's the name of the window]).
no, your real Problem is, that you overwrite the constructor for the Boolean Type.
1st. stick to coding conventions: Only classes start with an uppercase-letter.
2nd. local vars have to be declared with the var-Keyword (or let for block-scoped vars, or const).
otherwise you reference a var from a surrounding scope; and in the end, the global scope.
3rd. the equal-sign:
=== means typesafe comprison
3 === 3 //=> true
3 === '3' //=>false
== means simple comparison
3 == '3' //=> also true now
= means assignment, not comparison
var foo = 3;
if it inside of some other code like
var bar = 42 + (foo = 3);
//it works basically like
var bar = 42 + (function(){
foo = 3;
return 3; //NOT FOO!!! not even foo after the assignment
})();
//the same way, that this:
var bar = 42 + foo++;
//works basically like this:
var bar = 42 + (function(){
var result = foo;
foo = foo+1;
return result;
})();

While operator undefined

I want to make a small calculator in javascript.
I got the html code looking like this (for all the numbers)
<button type="button" onclick="calcNum(1)">1</button>
<button type="button" onclick="operator('+')">+</button>
var myNumbers = [];
The calcnumber function like this:
function calcNum(i) {
myNumbers.push(i);
var x = document.getElementById("screen").innerHTML = myNumbers.join("");
}
and the operator function like this:
function operator(op) {
var operator = op;
var y = document.getElementById("screen").innerHTML = operator;
}
My goal is to make it like this:
If I press 1,2,3 I want the screen element to display "123" (which it does) if I press "+" I want "+" to be displayed (which it does) however when the operator is pressed, and then a new number is pressed I want it to start on a new number, right now if I press "123" and then + and then "456" I get:
123456, instead I want it to display "456", hence starting on a new number. Hope it's all clear.
I figured I could add this to the calcNum function:
while(op == "undefined") {
keep pushing numbers // but this does not work
}
In the end I want to construct a calc function which takes all the numbers up to a operator is pressed as the FIRST number, then concatanate with the operator and the second number and adding them together.
I see several issues in your code but I don't know if it is due to the fact that you didn't copy all your code in your question.
First, the operator function is incorrect : you give a local variable the samename than the function. If you want the function return a value, use the returnkeyword.
I figured I could add this to the calcNum function:
while(op == "undefined") { keep pushing numbers // but this does
not work }
Where is opdefined? The only op I see is a local variable of the operatorfunction. It will always be undefined in calcNum.
Note also that if you want to test if a variable is undefined, you should not test
if (myVar == "undefined")
but
if(typeof myVar == "undefined")
Finally I'd change your code this way (should be tested though):
var currentNumber= "";
var entries = []
function calcNum(i) {
currentNumber +=i;
document.getElementById("screen").innerHTML = currentNumber;
}
function operator(op) {
var y = document.getElementById("screen").innerHTML = op;
//Note that you could already process the entered operations as if you clicked on '='
//and display the result instead of displaying the operation...
if(currentNumber != ""){//there must be a number entered before you click on an operator
entries .push(currentNumber);
entries .push(op);
currentNumber= "";
}
}
And you still need of course to implement what you do when you click on =...
Change your functions like this
var numbers = "";
function calcNum(i) {
myNumbers.push(i);
numbers +=i;
var x = document.getElementById("screen").innerHTML = numbers;
}
and
function operator(op) {
var operator = op;
var y = document.getElementById("screen").innerHTML = operator;
myNumbers.push(op);
numbers = "";
}
Declare above:
var leftOperand = null;
var lastOperator = null;
In calcNum:
if(lastOperator !== null) {
document.getElementById("screen").innerHTML = '';
leftOperand = myNumbers.join('');
myNumbers = [];
lastOperator = null;
}
// rest of the function
In operator:
lastOperator = op;
// rest of the function

Javascript consuming variables when variable a = variable b

I have a script setup like this (http://jsfiddle.net/YD66s/):
var countFull = new Array(0,1,2,3,4,5,6);
var countActive = new Array(0,1,2,3,4,5,6);
function pickRandom(a) {
if(arguments[1].length == 0) {
arguments[1] = arguments[0];
}
var m = Math.floor(Math.random()*arguments[1].length);
chosen = arguments[1].splice(m,1);
return chosen;
}
setInterval(function() {
pickRandom(countFull,countActive);
}, 1000);
When I run this I want the variable to be set for that function only. Instead it is affecting countFull towards the end because I make arguments[1] = arguments[0]. How in javascript can I just reference a variable but not consume it and ultimately arguments[1] becomes arguments[0].
Hope this makes sense. This is driving me nuts how different javascript variables are compared to other languages like PHP.
Javascript arrays are just pointers so when you do arguments[1] = arguments[0] you actually just set the pointer but the underlying arrays are the same. As a result, every time you modify arguments[1] you also modify arguments[0]. To do what you want, you need to copy the array. You could do it this way:
if (arguments[1].length == 0) {
for(var i = 0; i < arguments[0].length; i++) {
arguments[1][i] = arguments[0][i];
}
}
To copy an array, instead of referencing it, use copy = original.slice(0).

Get a limit on arrays (Javascript)

I've a problem with set a limit into my own lightbox for a gallery
<script>
var imagenumber = 0;
function btnleft(){
load = imagenumber-=1;
document.getElementById('lightboxcontent').innerHTML=imagelist[load];
}
function btnright(){
load = imagenumber+=1;
if (load==undefined){load=imagenumber-=1}
document.getElementById('lightboxcontent').innerHTML=imagelist[load];
}
</script>
Then the array
var imagelist=new Array(); // regular array (add an optional integer
imagelist[0]="image1.jpg"; // argument to control array's size)
imagelist[1]="image2.jpg";
imagelist[2]="image3.jpg";
When I click more then 3 times on the next button I got the error-message "undefined".
How should I do to get a limit on my arrays?
Try it with
function btnleft(){
var load = imagelist[imagenumber-=1];
if (load) // imagenumber in array boundaries
document.getElementById('lightboxcontent').innerHTML = load;
else
imagenumber = 0;
}
function btnright(){
var load = imagelist[imagenumber+=1];
if (load) // imagenumber in array boundaries
document.getElementById('lightboxcontent').innerHTML = load;
else
imagenumber = imagelist.length-1;
}
Yet, Arrays in Javascript have no limited size, they are more like (infinite) lists. You can hardly set a limit on their length - espcially not with the constructor, whose number argument is just for initialisation purposes.
You can use the length property of an array to check whether your index is in the array boundaries: i >= 0 && i < arr.length. My code just checks whether there is an item at that index (as your second function seems to intend, too) and resets the index otherwise.
I assume that clicking on the "next button" calls the btnright() function.
If that is the case then you are testing the wrong value for undefined. You could rewrite your function as:
function btnright(){
load = imagenumber += 1;
// Test the value at the index of the array, not your index variable.
if (imagelist[load] === undefined) {
load = imagenumber-= 1;
}
document.getElementById('lightboxcontent').innerHTML = imagelist[load];
}
Stylistically this is still no the best. Your load variable is not required since its value always duplicates imagenumber. You could refactor the function such:
function btnright() {
// If we have a new array value do something.
if (imagelist[imagenumber + 1] !== undefined) {
// Increment the index and load the new image.
document.getElementById('lightboxcontent').innerHTML = imagelist[++imagenumber];
}
}
function btnleft() {
// If we're not on the first image do something.
if (imagenumber !== 0) {
// Decrement the index and load the new image.
document.getElementById('lightboxcontent').innerHTML = imagelist[--imagenumber];
}
}

Categories