For a project I'm working on, I'm trying to make it so that when a button is pressed, an alert box pops up with a message. The message is randomly selected from an array.
I tried this already:
const rockTalk = [
'George is happy. Probably.',
'George is a bit parched, and would be most pleased if you provided him with a drink',
'George is going to sleep now.',
]
var randomItem = rockTalk[Math.floor(Math.random() * rockTalk.length)]
document.body.innerHTML = randomItem
var george = document.getElementById('georgeSprite')
function georgeSpeaks() {
alert('' + randomItem)
}
george.onclick = georgeSpeaks()
Your code is almost working. I have made a few changes so that it works.
The last comma in your rockTalk array adds 1 to the length of the array. In turn, this means that the random generator sometimes returns undefined.
var randomItem = rockTalk[Math.floor(Math.random() * rockTalk.length)] works fine, but you have placed it outside of the georgeSpeaks function. This means that it only runs once and so always produces the same message. I have placed it inside the function which corrects this.
document.body.innerHTML = randomItem doesn't do anything so I have removed it.
I have re-worked your code into a more conventional style.
Semi-colons are not required in JavaScript - they indicate the end of a statement - but they make code more readable.
This is your main mistake. Event handlers such as onclick require a function reference, which is the function name. Adding brackets executes the function, and in your case the returned value (undefined) is assigned to the event handler.
Your working code:
const rockTalk = [
'George is happy. Probably.',
'George is a bit parched, and would be most pleased if you provided him with a drink',
'George is going to sleep now.'
];
function georgeSpeaks() {
alert(rockTalk[Math.floor(Math.random() * rockTalk.length)]);
}
var george = document.getElementById('georgeSprite');
george.onclick = georgeSpeaks;
<button id='georgeSprite'>A rock</button>
Related
I was trying to crawl a very old website for a specific tag, I need to get it by it's for= attribute. So I used this piece of code.
var character = document.querySelectorAll("label[for=char_1]");
For some reason it returns an undefined, but I was using this script for a few days now and it worked like a charm. Here's the fun part. Typing that command in browsers console will result in undefined. But typing this alone:
document.querySelectorAll("label[for=char_1]");
Will return a proper NodeList. Why it won't assign to a variable...?
edit: It seems that deleting var and typing character without it will make it work. It's resolved but I would still love to get an answer to "why is this happening"?
edit2:
for (var i = 0; i < 15; i++) {
var character = document.querySelectorAll("label[for=char_" + i +"]");
console.log(character); // this will return [] from the script.
var color = character[0].children[0].style.color;
}
A simple for loop. All I get is Cannot read property 'children' of undefined. But I can type in the very same command document.querySelectorAll... and it will work in the browser and will return NodeList.
I had it working like this in a very hacky script. It worked.
var character1 = document.querySelectorAll("label[for=char_1]");
var characterColor1 = character1[0].children[0].style.color;
edit3:
var character1 = document.querySelectorAll("label[for=char_1]");
var characterColor1 = character1[0].children[0].style.color;
var character2 = document.querySelectorAll("label[for=char_2]");
var characterColor2 = character2[0].children[0].style.color;
// ...
The above code works without a single problem though. I don't think it's DOM not being ready as this code is also run from Greasemonkey script and it works. The only difference is the for loop.
var x = ""; // returns undefined, because it's a var assignment.
var elements = document.querySelectorAll('div');
That's expected behavior when pasted into the console.
edit: It seems that deleting var and typing character without it will make it work. It's resolved
I'm afraid you're creating a global scope variable now. or perhaps characters is an already defined variable in that scope.
Buhah, as I said in edit 3 "the only difference is the for loop". I was so busy trying to find an answer in the DOM-related things that I made the simplest mistake ever done in programming.
See?
char_1
With...
for(var i = 0...)
0! And I was testing char_1 in the browser instead of char_0. Which - truly - returns [] instead of something useful. Time to go on a holiday break I guess, my brain seems to be there already. :)
I am trying to get a JavaScript code to select a string of text at random from an array. This is what I have so far but it doesn't seem to be working, appreciate the help. Don't know if this matters but this is for a website.
var myArray = ['One does not simply click the acorn'.'acorn spices all the rage with Martha Stewart', 'Once more into the acorn tree my friends','Acornbook launches as first acorn based social media'];
var rand = myArray[Math.floor(Math.random() * myArray.length)];
var postmessage = + myArray;
You are using the dot "." instead of comma "," among the very first two elements in myArray.
You should use comma there as below.
var myArray = ['One does not simply click the acorn','acorn spices all the rage with Martha Stewart', 'Once more into the acorn tree my friends','Acornbook launches as first acorn based social media'];
You're getting the random value in the correct way, but the issue is what happens on line 3.
var postmessage = + myArray;
Putting a + sign in front of an array will try to turn it into a number, so doing + myArray results in NaN which is probably not what you wanted.
I'm going to guess that you probably wanted to store the random phrase in post message. Which would instead look like:
var postmessage = rand;
I think you made a simple mistake by accident. You are trying to add an array to a variable. I assume you wanted to add the randomly picked element so you would want on the third line:
var postmessage = + rand;
<script>
var postmessage = ''; // initialization for getting the random selected text from array
var myArray = ['One does not simply click the acorn', 'acorn spices all the rage with Martha Stewart', 'Once more into the acorn tree my friends', 'Acornbook launches as first acorn based social media'];
var rand = myArray[Math.floor(Math.random() * myArray.length)];
var postmessage = rand;
</script>
I've searched a lot but can't find an answer...
I have a list of quotes and every time I click the button I want it to go to a new quote.
Can someone please explain what's wrong here and how I should fix it?
<script language="Javascript">
function buttonClickHandler() {
var textField = document.getElementById("textField");
var quotes = new Array();
var nextQuote = 0;
quotes[0] = "Don't be so humble - you are not that great.";
quotes[1] = "Moral indignation is jealousy with a halo.";
quotes[2] = "Glory is fleeting, but obscurity is forever.";
quotes[3] = "The fundamental cause of trouble in the world is that the stupid are cocksure while the intelligent are full of doubt.";
quotes[4] = "Victory goes to the player who makes the next-to-last mistake.";
quotes[5] = "His ignorance is encyclopedic";
quotes[6] = "If a man does his best, what else is there?";
quotes[7] = "Political correctness is tyranny with manners.";
quotes[8] = "You can avoid reality, but you cannot avoid the consequences of avoiding reality.";
quotes[9] = "When one person suffers from a delusion it is called insanity; when many people suffer from a delusion it is called religion.";
nextQuote++;
textField.value = quotes[nextQuote];
}
</script>
I found this code on the internet and when I use this code, it changes the text on every click.
var currentValue = parseInt(textField.value);
// Add one
currentValue++;
// Put it back with the new +1'd value
textField.value = currentValue;
var quotes = new Array();
The code I used for my array is nearly the same but it doesn't change the text per click. Is there something special I need to do for arrays? Help!!
It wont change it because you declare the array and the index inside your handler, so every time you click you get the quote at index 1. Define the index outside the handler (as well as the array) and increment inside the handler:
var quotes = new Array();
var nextQuote = 0;
quotes[0] = "Don't be so humble - you are not that great.";
quotes[1] = "Moral indignation is jealousy with a halo.";
quotes[2] = "Glory is fleeting, but obscurity is forever.";
quotes[3] = "The fundamental cause of trouble in the world is that the stupid are cocksure while the intelligent are full of doubt.";
quotes[4] = "Victory goes to the player who makes the next-to-last mistake.";
quotes[5] = "His ignorance is encyclopedic";
quotes[6] = "If a man does his best, what else is there?";
quotes[7] = "Political correctness is tyranny with manners.";
quotes[8] = "You can avoid reality, but you cannot avoid the consequences of avoiding reality.";
quotes[9] = "When one person suffers from a delusion it is called insanity; when many people suffer from a delusion it is called religion.";
function buttonClickHandler() {
var textField = document.getElementById("textField");
textField.value = [++nextQuote];
}
Because every time the function is called nextQuote is re-set to 0
You're assinging nextQuote to 0 every single time you call the handler.
var nextQuote = 0;
Try doing this instead:
var quotes = new Array();
quotes[0] = "Don't be so humble - you are not that great.";
quotes[1] = "Moral indignation is jealousy with a halo.";
quotes[2] = "Glory is fleeting, but obscurity is forever.";
quotes[3] = "The fundamental cause of trouble in the world is that the stupid are cocksure while the intelligent are full of doubt.";
quotes[4] = "Victory goes to the player who makes the next-to-last mistake.";
quotes[5] = "His ignorance is encyclopedic";
quotes[6] = "If a man does his best, what else is there?";
quotes[7] = "Political correctness is tyranny with manners.";
quotes[8] = "You can avoid reality, but you cannot avoid the consequences of avoiding reality.";
quotes[9] = "When one person suffers from a delusion it is called insanity; when many people suffer from a delusion it is called religion.";
var nextQuote = 0;
var textField = document.getElementById("textField");
function buttonClickHandler() {
if(nextQuote < 9) {
nextQuote++;
} else {
nextQuote = 0;
}
textField.value = quotes[nextQuote];
}
try something like
var nextQuote = Math.floor((Math.random()*9)+1);
instead of your:
var nextQuote =0;
later change the 9 to your array size, and add it after you've declared all the values into your array.
The difference is the code that works gets the value to increment from outside of buttonClickHandler
var currentValue = parseInt(textField.value);
where as you reinitialise it every time buttonClickHandler is called
var nextQuote = 0;
I think it will work if you replace this declaration with
if (window.nextQuote == null) {
window.nextQuote = 0
} else {
window.nextQuote++
}
As previously posted answers have already stated, the problem is caused because nextQuote is defined inside of buttonClickHandler and thus destroyed every time the function finishes executing and is recreated and initialized to 0 every time the function begins.
You seem to be learning JavaScript using some very old tutorials, the following code will show how this could be refactored to a more modern style.
<script language="Javascript">The language attribute of the <script> tag was deprecated a very long time ago. Don't use it. It was replaced by the type attribute, however don't use the type attribute either. Just a plain <script> tag works in all browsers, they all default to JavaScript since it was the only language to ever gain any traction as a client-side scripting language.
<script>
(function (document) { // Use a self-invoking function to keep our variables
// out of the global scope
"use strict"; // Force the browser into strict mode
var nextQuote = 0, // instead of using separate var statements you can use
// a comma to include all of your variable declarations
// in one statement.
/* Since we will be using the textField DOM element a lot, lets cache a
copy in a variable outside of the handler instead of enduring the
overhead of getElementById every time the handler runs,
querying the DOM is slow.
*/
textField = document.getElementById("textField"),
/* Instead of using new Array(), use an array literal. Literals are
shorter and behave in a more predictable way than the Array
constructor. Another benefit to using a literal is that you can
create the array and initialize it's values in one step avoiding
the tedious quotes[0] = "..."; quotes[1] = "..."; pattern of the
original code. Also, if you want to reorder the items in the list
you don't have to renumber them too.
*/
quotes = [
"Don't be so humble - you are not that great.",
"Moral indignation is jealousy with a halo.",
"Glory is fleeting, but obscurity is forever.",
"The fundamental cause of trouble in the world is that the stupid are cocksure while the intelligent are full of doubt.",
"Victory goes to the player who makes the next-to-last mistake.",
"His ignorance is encyclopedic",
"If a man does his best, what else is there?",
"Political correctness is tyranny with manners.",
"You can avoid reality, but you cannot avoid the consequences of avoiding reality.",
// The last item in the list should not have a comma after it, some
// browsers will ignore it but others will throw an error.
"When one person suffers from a delusion it is called insanity; when many people suffer from a delusion it is called religion."
];
function buttonClickHandler() {
nextQuote++;
// roll back to 0 if we reach the end
if (nextQuote >= quotes.length) {
nextQuote = 0;
}
textField.value = quotes[nextQuote];
}
document.getElementById('button').addEventListener("click", buttonClickHandler, false);
}(document)); /* This is the end of the self-invoking function. The document
object is being passed in as an argument. It will be imported
into the self-invoking function as a local variable also named
document. There are a couple of reasons to do this. Having it
aliased as a local variable will make any references to it
quicker since the browser will not have to look any further
up the scope-chain. Also, if this code is minified, the local
variable will be renamed to a shorter (often 1 character long)
name, saving download time, where references to the built-in
global document object would not.
*/
</script>
The self-invoking function that wraps the code is a very common pattern in modern JavaScript, it would be good to become familiar with it.
Using strict mode will help you avoid a number of easy to create bugs.
If you are deploying JavaScript code into the wild you should be minifying it. Having a build process can make this easy by automating it for you. I would recommend Grunt, it has lots of pre-built tasks to make minifying and other common build tasks easy. It can be a bit tricky to set up at first but there are a lot of great articles out there that can make it much easier to understand.
I'm writing code where there will be several actions in an array.
var randomStringsWriting = [
'Write about ' + randomObjectsPlural,
'Think about ' + randomObjectsPlural,
'Love ' + randomObjectsPlural
the "randomObjectsPlural" variable is another array with nouns
var randomObjectsPluralList = [
'cats',
'dogs',
'people',
]
In order to make it easier for me to write one variable instead of an equation, I set this initially (Note that THIS is the variable in the initial array, and not "randomObjectsPluralList")
var randomObjectsPlural = randomObjectsPluralList[0]
I would like the text to update whenever I click, so I wrote this function:
$("#screen" ).click(function(){
randomObjectsPlural = randomObjectsPluralList[Math.floor(Math.random()*randomObjectsPluralList.length)];
});
Oddly, when I click to randomize, the same "randomObjectsPlural" variable is kept, despite the click to randomize. For example, the screen would eventually display...
Write about cats
Think about cats
Love cats
...when I would want something more like
Write about cats
Think about people
Love dogs
The only way that the noun would change is if I refreshed the page. What exactly is happening here?
I'm not sure how you have wired all this up but when you click you have to randomise each item again and again.
What you have shown so far would indicate that you only set the randomStringsWriting array ones at the start, hence you only update it ones at page load.
You are also setting each item to randomObjectsPlural but it seems you are only setting the variable up ones. You would need to randomise a new randomObjectsPlural for each one.
Again, as I have no idea how you have actually wired it all up below is a demo to achieve what you are looking for.
The below is an example. You still will need to take the logic and adapt it into your own implementation.
Assuming the following HTML:
<button id="screen">Click</button>
<div id="output"></div>
The following JavaScript would do the trick:
var getRandomListItem = function () {
return randomObjectsPluralList[Math.floor(Math.random() * randomObjectsPluralList.length)]
};
var randomObjectsPluralList = [
'cats',
'dogs',
'people']
$("#screen").click(function () {
var randomStringsWriting = [
'Write about ' + getRandomListItem(),
'Think about ' + getRandomListItem(),
'Love ' + getRandomListItem()]
$('#output').html(randomStringsWriting.join('<br />'));
});
DEMO - Randomizing the string values
As you are only picking a random value out of a possible 3 it is very likely off course that you still get all 3 random values to be the same.
If you want random + different then you also need to keep track of each value which already has been selected until all have been picked, then re-set the tracker but that is a slightly more involved process.
I'm trying to debug some javascript I wrote and can't figure out why it's not working. If I hard code the variables it works fine, but if I use document.getElementById('id').value to get the variable it fails.
The example below works fine but as soon as I un-comment the commented lines it doesn't. Printing the variables before and after the second section they seem to be identical.
Really don't get what's going on. Maybe I just need to sleep on it, but if anyone's got suggestions that would be great!
roof_width = 5;
roof_depth = 3;
panel_width = 2;
panel_depth = 1;
panel_power = 200;
roof_margin = 0.100;
panel_gap = 0.05;
roof_width = document.getElementById('roof_width').value;
roof_depth = document.getElementById('roof_depth').value;
// panel_width = document.getElementById('panel_width').value;
// panel_depth = document.getElementById('panel_depth').value;
panel_power = document.getElementById('panel_power').value;
// roof_margin = document.getElementById('roof_margin').value;
panel_gap = document.getElementById('panel_gap').value;
Are you trying to add numbers that are in text boxes? Because of the way JavaScript's variable typing system works (combined with the overloading of the + operator), 2 + 2 === 4 (adding numbers) but '2' + '2' === '22' (string concatenation). Try changing the lines to, for example:
panel_width = parseFloat(document.getElementById('panel_width').value);
or alternatively:
panel_width = Number(document.getElementById('panel_width').value);
This will ensure that JavaScript treats the numbers as numbers rather than as strings.
JavaScript parameters can't be called in the same way that you're calling HTML elements. In order to call
document.getElementById('roof_margin').value;
you need to assign 'roof_margin' to an HTML form element.
Pherhaps you have multiple dom elements with the same id? Remember the dom element ID must be unique. I suggest you to use jquery for interacting javascript with html.
Make sure your code is in an onload function. Otherwise the elements may not have been loaded into the DOM yet.
window.onload = funciton(){/* code here */};