I have a bunch of spans, they are set to display in-line block with a width and height of 60px, i want javascript to pick a random span from all of them and apply a color to it. I don't really even know where to begin with this. Any help would be appreciated.
For starters,
var elts = document.getElementsByTagName('span');
if using jQuery:
elts = $('span')
so now elts contains all the spans in the document.
The tricky part is selecting a random element within. We have to use Math.floor(Math.random() * elts.length) to select a random index. This is an earful, so the explanation:
Math.random() returns a random from [0,1).
elts.length is the length of the array. We multiply this by Math.random() to get a random array index from 0 to elts.length exclusive.
Math.floor() rounds down, so that we don't get an out of bounds exception.
Put it all together:
var myRandomSpan = elts[Math.floor(Math.random() * elts.length)]
and there you have it. You can do what you please with myRandomSpan.
You say you don't know where to begin. Well, with a little thought it becomes apparent:
1) Work out how to generate a random number in JS (easy Googling)
2) Work out how to pick out a random element form an array using point 1
3) Realise that a nodeset, e.g. as the result of getElementsByTagName or querySelectorAll is array-like (but not actually an array), and so we can pick out a particular element of it via square-bracket syntax, as with arrays. We can therefore apply point 2 to this nodeset.
So:
var
spans = document.querySelectorAll('span'),
span = spans[Math.floor(Math.random() * spans.length];
I have no idea if this will work - random code I pulled from various searches but in theory you could put all your spans into a array, count the length, generate random number bsaed on that length and access it via indecies:
var numSpans $("#container span").size();
var optionTexts = [];
// populat our span array
$("#container span").each(function() { optionTexts.push($(this).text()) });
var random = NumMath.floor(Math.random() * optionText.length);
var randomSpan = optionText[random];
You can give an integer id to your spans
<span id=1></span>
<span id=2></span>
...
<span id=100></span>
So, you just have to make a random number in between your ids. To generate a random integer between to numbers you can use this function:
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var randomID = getRandomInt(1, 100);
Then, with your random integer you can select the span like this:
document.getElementById(randomID)
If you are using jQuery you can change the background-color like this:
$("#" + randomID).css("background-color", {new_color})
Related
I am using Math.random to create a unique value.
However , it looks like after some days , if i run the same script it produces the same value that created earlier.
Is there any way to create unique value every time when ever i run the script.
Below is my code for the random method.
var RandomNo = function (Min,Max){
return Math.floor(Math.random() * (Max - Min + 1)) + Min;
}
module.exports = RandomNo;
The best way to achieve a unique value is to use Date() as milliseconds. This increasing time representation will never repeat.
Do it this way:
var RamdomNo = new Date().getTime();
Done.
Edit
If you are bound to length restrictions, the solution above won't help you as repetition is predictable using an increasing number the shorter it gets.
Then I'd suggest the following approach:
// turn Integer into String. String length = 36
function dec2string (dec) {
return ('0' + dec.toString(36)).substr(-2);
}
// generate a 20 * 2 characters long random string
function generateId () {
var arr = new Uint8Array(20);
window.crypto.getRandomValues(arr);
// return 5 characters of this string starting from position 8.
// here one can increase the quality of randomness by varying
// the position (currently static 8) by another random number <= 35
return Array.from(arr, this.dec2string).join('').substr(8,5);
}
// Test
console.log(generateId());
This pair of methods generates a 40 characters long random string consisting of letters and digits. Then you pick a sequence of 5 consecutive characters off it.
I am using the following JS function to generate unique IDs, which I got from another StackOverflow thread:
function generateUniqueID() {
return Math.round(new Date().getTime() + (Math.random() * 100));
}
I see that it combines the current Date/Time with an additional Randomizer.
Nonetheless, I verified that I'm getting collisions on every 4th or 5th operation of quickly adding items with IDs.
The function is called inside a JS loop to generate IDs from the list of current elements.
jQuery.each(mainEvents, function(index, item) {
// ...
// Generate gaps
gapEvents.push({"gapEventID" : "event-GAP" + generateUniqueID(),
"other" : other });
}
Is this function unreliable? Could it allow collisions in quick JS loop iterations?
I've pretty much ruled out "outside causes" (i.e. that this function isn't the culprit but something else could be), but if that's the case, I can't understand why Math.random() wouldn't keep me safe.
Very much so. You can use new Date().getTime() to get a unique id under the assumption that it takes longer than 1ms for each iteration. As you can tell from your data, that is false. Combined with an RNG that uses Math.floor, it's very possible to get repeated values. You will get repeat times whenever the interval is < 1ms. If you want unique IDs based around the concept of an RNG, I'd say just using Math.random() to the 10^15 is a better choice. 10^15 is the max size integer digit length that will never go past Number.MAX_SAFE_INTEGER.
Math.floor(Math.random() * Math.pow(10, 15))
Is this function unreliable?
In my opinion it really is.
Infact new Date().getTime() is an integer number that increases by 1 each millisecond, while Math.random() * 100 is a pseudo random number that gives a number in a range from 0 to 99.
So their sum might really repeat often if the function is called many times rapidly.
Think if the function is called two times per millisecond, it becomes very likely to have the same number twice. It has 1/100 of probability to happen (and these are pretty much the results I'm getting considering that I'm generating a list of 10.000 ids in about 1 second using that function and getting ~100 duplicates, which is pretty consistent as order of magnitude)
A random value is never a unique value. Even with a timestamp you can't guarantee that the outcome is 100% unique. However, you could minimize this by generating a larger (random) value.
Using a timestamp however, you cover yourself when there are multiple pushes at the same time. Using an extra random will create an almost unique value which, in most use cases is unique.
I'd suggest though to make that random value longer. Or create a GUID instead.
Create GUID / UUID in JavaScript?
Based on the responses the following compares the suggested methods.
But I think I'm going in the wrong direction for my needs. I will be using the ID/Sequence on the server-side to ensure uniqueness.
function run() {
var nums1 = new Set(), nums2 = new Set(), nums3 = new Set();
for (var i = 0; i < 10000; i++) {
nums1.add(originalMethod());
}
for (var i = 0; i < 10000; i++) {
nums2.add(concatMethod());
}
for (var i = 0; i < 10000; i++) {
nums3.add(random10To18thMethod());
}
console.clear();
console.log('Original Method set: ' + nums1.size);
console.log('Concat Method set: ' + nums2.size);
console.log('Math.Random 10^18 set: ' + nums3.size);
function originalMethod() {
return Math.round(new Date().getTime() + (Math.random() * 100));
}
function concatMethod() {
return Math.round(new Date().getTime() + '' + (Math.random() * 100));
}
function random10To18thMethod() {
return Math.random() * Math.pow(10, 18);
}
}
<button onclick="run()">Run Algorithms</button>
When I click the 'Random' link on my navbar (bootstrap) it refers to Javascript code (below) taking me to a random page on my mock website.
However I would like to add a feature, so if I'm on, say Link[2]=fed-rates.html, when I press the 'Random' link on my navbar it always takes me away from the page I'm currently on (that is, it ignores Link[2]).
I'm wondering whether this is possible, would be great to get some ideas.
Javascript code:
function randomlinks(){
var myrandom=Math.round(Math.random()*2)
var links=new Array()
links[0]="articles/how-to-trade-oil.html"
links[1]="articles/usd-yen-gbp.html"
links[2]="articles/fed-rates.html"
window.location=links[myrandom]
}
// above is for all web pages
function randomlinksarticle(){
var myrandom=Math.round(Math.random()*2)
var links=new Array()
links[0]="how-to-trade-oil.html"
links[1]="usd-yen-gbp.html"
links[2]="fed-rates.html"
window.location=links[myrandom]
}
// above is so navbar link still works on the linked pages, with the way I have the folder directory setup
New code that comes up with "/undefined" page:
function randomlinksarticle(){
var myrandom=Math.round(Math.random()*2)
var links=new Array()
links[0]="how-to-trade-oil.html"
links[1]="usd-yen-gbp.html"
links[2]="fed-rates.html"
links.forEach(function(link, index) {
if (location.href.indexOf(link) !== -1) {
links.splice(index, 1);
}});
window.location=links[myrandom]
You can do the following:
links.forEach(function(link, index) {
if (location.href.indexOf(link) !== -1) {
links.splice(index, 1);
}
});
This looks through all the links and checks if they exist in the current URL. If they do, it removes them from the list using the splice function.
Add this code after setting link[2], since that's when it should be removing the current page.
Edit: I also noticed that your random function isn't evenly distributed. Not that it matters that much, but it could cause problems for you. The reason for this is that there are many more numbers between 0 and 2 that round to 1 than to 0 or two. In order to get a zero from your random number scale, Math.random() has to be less than 0.5. Likewise, it has to be greater than or equal to 1.5 to get a 2. you have a 0.5/2 or 1/4 probability for 0 and 2. This leaves a 1/2 probability for getting one, which makes sense since all numbers between 0.5 and 1.5 would give you a 1.
tl;dr: Use math.floor(Math.random() * (maximum + 1)) rather than Math.round(Math.random() * maximum) for generating random numbers.
Also, if you want a less repetitive way to do this, you could substitute both functions for something like this:
function randomLink() {
var links = Array.prototype.slice.call(arguments, 0); //Turns the function's arguments into an array
links.forEach(function(link, index) { //Loops through all the links
if (location.href.indexOf(link) !== -1) { //If the link text is contained in the url
links.splice(index, 1); //Remove the link from the links array
}
});
var rand = Math.floor(Math.random() * links.length); //Choose a number between 0 and links.length - 1
window.location = links[rand]; //Visit the link
}
You could call this like randomLink("first_page.html", "second_page.html") with an arbitrary number of pages.
Hello everyone! I have completed a couple of brief courses in JavaScript, and I have now moved on to Heads Up: JavaScript, which has been a lot of fun and is helping to cement my learning. I did run into something I didn't understand, though. In the following piece of code, I understand what the program generally does when it executes, but in attempting to trace each step of execution, I realized that I am confounded by the "What/Why/How" of a particular segment. Here's the code for the sample program I'm looking at:
function makePhrases() {
var words1 = ["24/7", "multi-tier", "30,000 foot", "B-to-B", "win-win"];
var words2 = ["empowered", "value-added", "oriented", "focused", "aligned"];
var words3 = ["process", "solution", "tipping-point", "strategy", "vision"];
var rand1 = Math.floor(Math.random() * words1.length);
var rand2 = Math.floor(Math.random() * words2.length);
var rand3 = Math.floor(Math.random() * words3.length);
var phrase = words1[rand1] + " " + words2[rand2] + " " + words3[rand3];
alert(phrase);
}
makePhrases();
This is the segment that has been confusing for me:
var rand1 = Math.floor(Math.random() * words1.length);
var rand2 = Math.floor(Math.random() * words2.length);
var rand3 = Math.floor(Math.random() * words3.length);
I get that it's the part of the code that randomizes which item from each array is chosen to form the new "random phrase", but I don't understand how it's doing so. I also hadn't known previously that Math.random or Math.floor could be applied to strings (must be because they're in an array, which is essentially a number?), or the how/why of using Math.random or Math.floor with strings.
Additionally, why do we need to use .length with this incarnation? What does it do? I appreciate your wisdom here, and taking the time to help someone who's new to coding, and still has so much to learn!
Let's look at the code:
var rand1 = Math.floor(Math.random() * words1.length);
Math.random() returns a number between 0 and 0.999999...
words1 is the list of words to choose from.
words1.length is the size of the list, the number of items, 5 in this case.
Math.random() * words1.length returns a number between 0 and 4.99999...
Finally use Math.floor() to get a whole number between 0 and 4.
This number is then used as an index in words1, so words1[rand1].
So the Math operations are never used on a string, fetching the string in only the last step.
All that's happening is Math.random() is being used as a multiplier against the number of elements in the respective arrays (the '.length' property) to create an index value. It isn't being applied to a string; just as part of an expression to determine an index into a string array.
You want to pick a random element from an array. So you need an index, in other words a random number from 0 to 4 (because your length is 5). Math.random will give you a random number between 0 and 1 (exclusive of 1). So to turn that into a random number between 0 and 4 you need to multiple by the length of 5.
Then, since we need an integer, not a floating point number, we use Math.floor to truncate it to a integer.
Math.random() //Return a random number between 0-1
words1.length() //Return the length of the array
Math.floor() //Return the closest integer less than or equal to a given number.
Now the expressions:
(Math.random() * words1.length)
Will return a random number between 0 and the length of the array. Could be a float, like 3,4 for example:
Math.floor(Math.random() * words1.length)
Will return an integer number between 0 and the length of the string, so you can use it now as the string (behaving like an array) indexer.
Note: Note that the random number is between 0 (inclusive) and 1 (exclusive), that's why is secure to use Math.floor(), to avoid an exception, and that's why is not used Math.ceiling.
What I want my function to achieve for my javascript function is for every second to either randomly subtract or add (a random number) to a number held in a div.
Here's what I have so far.
It doesn't work, it seems to append the number to the end of the div value (100), and also it doesn't take into account that I want it to either randomly add or subtract (it just adds at the moment)
setInterval(function(){
random = (Math.floor((Math.random()*15)+1));
currentnumber = document.getElementById('number');
document.getElementById('number').innerHTML = currentnumber + random;
}, 1000);
parse the current value as an integer, and then do another math.random and use it to decide negative or positive. Lastly, you need to use the innerHTML of currentnumber, not the entire node. So something like this should work:
setInterval(function(){
random = (Math.floor((Math.random()*15)+1));
var plusOrMinus = Math.random() < 0.5 ? -1 : 1;
random = random * plusOrMinus;
currentnumber = document.getElementById('number');
document.getElementById('number').innerHTML = parseInt(currentnumber.innerHTML) + random;
}, 1000);
WORKING FIDDLE
.innerHTML returns you a string which you'll need to parse into an integer to perform the addition or subtraction. Have a look at a number of methods listed in the following SO question
How do I convert a string into an integer in JavaScript?
currentnumber is a DOM object, and you can't add that to a number.
var div = document.getElementById('number');
div.innerHTML = Number(div.innerHTML) + 3;
Notice you are getting the innerHTML of the div, converting that to a Number(), adding your random number to it, and THEN setting your div.innerHTML to your new value.
http://jsfiddle.net/9LqQG/1/
Maybe try something like this:
setInterval(function(){
random = (Math.floor((Math.random()*15)+1));
currentnumber = parseInt(document.getElementById('number').innerHTML);
document.getElementById('number').innerHTML = currentnumber + random;
}, 1000);
Your currentnumber variable needs to get the innerHTML of the element, then parse the string into an integer.
jsFiddle