124

I want to display YouTube videos on my website, but I need to be able to add a unique id for each video that's going to be shared by users. So I put this together, and I have run into a little problem. I am trying to get the JavaScript to add a random string for the div id, but it's not working, showing the string:

<script type='text/javascript' src='jwplayer.js'></script>
<script type='text/javascript'>
function randomString(length) {
    var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split('');

    if (! length) {
        length = Math.floor(Math.random() * chars.length);
    }

    var str = '';
    for (var i = 0; i < length; i++) {
        str += chars[Math.floor(Math.random() * chars.length)];
    }
    return str;
}

var div = randomString(8);
</script>

<div id='div()'>This text will be replaced</div>

<script type='text/javascript'>
  jwplayer('div()').setup({
    'flashplayer': 'player.swf',
    'file': 'http://www.youtube.com/watch?v=4AX0bi9GXXY',
    'controlbar': 'bottom',
    'width': '470',
    'height': '320'
  });
</script>
7
  • 1
    Perhaps this would be helpful stackoverflow.com/questions/105034/… Commented Jul 28, 2011 at 14:45
  • I typically just create a global var and increment it :P Commented Jul 28, 2011 at 14:48
  • Looks like the OP can generate a random string, but he can't get it into the id of the div. Until I get confirmation I wont post a solution. Commented Jul 28, 2011 at 14:49
  • @Jamiec yes that is my problem i cant get it into the divs ID Commented Jul 28, 2011 at 14:50
  • @sarsar - jQuery or vanilla javascript? Commented Jul 28, 2011 at 14:50

18 Answers 18

211

I really like this function:

function guidGenerator() {
    var S4 = function() {
       return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
    };
    return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}

From Create GUID / UUID in JavaScript?

Sign up to request clarification or add additional context in comments.

5 Comments

... but not really the problem he is asking about :-)
But exactly what I've Googled for :=)
Warning: It could create Guid starting with number. Can't use that directly as id. Id should start with _ or letter. :)
@jbyrd, this will guarantee unique id, but it can't guarantee correct HTMLElement id. The id for element can't begin from number. stackoverflow.com/questions/6860853/…
For anyone stumbling upon here: This is not how real GUIDs work, which may be relevant if used for another purpose. The 13th and 17th hex digits are special and need to be set to 4 and one of {8,9,A,B,C,D}, respectively. en.wikipedia.org/wiki/Universally_unique_identifier#Format
93

2018 edit: I think this answer has some interesting info, but for any practical applications you should use Joe's answer instead.

A simple way to create a unique ID in JavaScript is to use the Date object:

var uniqid = Date.now();

That gives you the total milliseconds elapsed since January 1st 1970, which is a unique value every time you call that.

The problem with that value now is that you cannot use it as an element's ID, since in HTML, IDs need to start with an alphabetical character. There is also the problem that two users doing an action at the exact same time might result in the same ID. We could lessen the probability of that, and fix our alphabetical character problem, by appending a random letter before the numerical part of the ID.

var randLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
var uniqid = randLetter + Date.now();

This still has a chance, however slim, of colliding though. Your best bet for a unique id is to keep a running count, increment it every time, and do all that in a single place, ie, on the server.

13 Comments

Dates by themselves are not very random since two users doing the same operation at the same time can get the same date value. If you combine a date with a random number function, you will get something much more unique.
Plus the valueOf representation is a number, which is not a valid html id (they have to start with an alpha character)
@Chris my answer was not factually incorrect, it just wasn't the best from answers here. I added some things.
Collide: var arr = [Date.now(), Date.now()];. Easy to reproduce on modern CPUs.
This is a very bad solution to the problem of any type of Id-generation, in particular for the actual question being posed (hinting that the question is not read). It is pretty likely that you'll end up with the same id for two divs (one millisecond is a very long time). The answer from @jfriend00 is much better (in particular the "Another way to do it"). If you're out to get very-likely-not-globally-colliding ids, then a bunch of random alphanums are much better - or just go for GUIDs (UUIDs) like 'Joe' suggests.
|
83

Here is the reusable function to generate the random IDs :

function revisedRandId() {
     return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10);
}

// It will not start with the any number digit so it will be supported by CSS3

3 Comments

This could result in an empty string, which wouldn't be a valid ID. var lengths = {}, total = 1000000; for(var i = 0; i < total; i++){ var newLength = revisedRandId().length; lengths[newLength] = (lengths[newLength] || 0) + 1; } lengths[0] / total - it looks like it would give an invalid ID about 0.03% of the time, so not often, but definitely possible.
Math.random().toString(36) -> "0.v6doivsvnkg". Discarding first two characters is redundant as they are removed with the replace command: Math.random().toString(36).replace(/[^a-z]+/g, '') -> "vdoivsvnkg".
function revisedRandId () { return Math.random().toString(36).replace(/^0\./, '_') } and now it passes @1j01's test.
36

i like this simple one:

function randstr(prefix)
{
    return Math.random().toString(36).replace('0.',prefix || '');
}

since id should (though not must) start with a letter, i'd use it like this:

let div_id = randstr('youtube_div_');

some example values:

youtube_div_4vvbgs01076
youtube_div_1rofi36hslx
youtube_div_i62wtpptnpo
youtube_div_rl4fc05xahs
youtube_div_jb9bu85go7
youtube_div_etmk8u7a3r9
youtube_div_7jrzty7x4ft
youtube_div_f41t3hxrxy
youtube_div_8822fmp5sc8
youtube_div_bv3a3flv425

Comments

33

I think some folks here haven't really focused on your particular question. It looks like the problem you have is in putting the random number in the page and hooking the player up to it. There are a number of ways to do that. The simplest is with a small change to your existing code like this to document.write() the result into the page. I wouldn't normally recommend document.write(), but since your code is already inline and what you were trying do already was to put the div inline, this is the simplest way to do that. At the point where you have the random number, you just use this to put it and the div into the page:

var randomId = "x" + randomString(8);
document.write('<div id="' + randomId + '">This text will be replaced</div>');

and then, you refer to that in the jwplayer set up code like this:

jwplayer(randomId).setup({

And the whole block of code would look like this:

<script type='text/javascript' src='jwplayer.js'></script>
<script type='text/javascript'>
function randomString(length) {
    var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz'.split('');

    if (! length) {
        length = Math.floor(Math.random() * chars.length);
    }

    var str = '';
    for (var i = 0; i < length; i++) {
        str += chars[Math.floor(Math.random() * chars.length)];
    }
    return str;
}

var randomId = "x" + randomString(8);
document.write('<div id="' + randomId + '">This text will be replaced</div>'); 

  jwplayer(randomId).setup({
    'flashplayer': 'player.swf',
    'file': 'http://www.youtube.com/watch?v=4AX0bi9GXXY',
    'controlbar': 'bottom',
    'width': '470',
    'height': '320'
  });
</script>

Another way to do it

I might add here at the end that generating a truly random number just to create a unique div ID is way overkill. You don't need a random number. You just need an ID that won't otherwise exist in the page. Frameworks like YUI have such a function and all they do is have a global variable that gets incremented each time the function is called and then combine that with a unique base string. It can look something like this:

var generateID = (function() {
    var globalIdCounter = 0;
    return function(baseStr) {
        return(baseStr + globalIdCounter++);
    }
})();

And, then in practical use, you would do something like this:

var randomId = generateID("myMovieContainer");  // "myMovieContainer1"
document.write('<div id="' + randomId + '">This text will be replaced</div>');
jwplayer(randomId).setup({

7 Comments

This answer's fine too, but I assume that inside that jwplayer code should be div not 'div()'.
@jfriend00 Jamiec is right i need to be able to match the div id with the jw player code here jwplayer('div').setup({
Yeah, I had no idea what the jwplayer code was doing or how it worked. I didn't know that was part of the question. Anyway, I looked that up on the web and modified my code so that the div with the random number ID is now passed to the jwplayer setup too. FYI, since CSS IDs are technically not allowed to start with a digit, I also put a letter at the beginning.
I added a somewhat simpler way to do this at the end of my answer. A random number is not actually needed in this case, just a monotomically increasing number combined with a unique base string.
If you need uniqueness across files, a random ID might be warranted.
|
19

I also needed a random id, I went with using base64 encoding:

btoa(Math.random()).substring(0,12)

Pick however many characters you want, the result is usually at least 24 characters.

2 Comments

i like how it always starts with 'MC4' (meaning '0.') because it makes sure the id doesn't start with a number.
i'd use it like that instead: btoa(Math.random()).replace(/=/g,'') because you shouldn't put '=' in there.
14

Based on HTML 4, the id should start from letter:

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

So, one of the solutions could be (alphanumeric):

  var length = 9;
  var prefix = 'my-awesome-prefix-'; // To be 100% sure id starts with letter

  // Convert it to base 36 (numbers + letters), and grab the first 9 characters
  // after the decimal.
  var id = prefix + Math.random().toString(36).substr(2, length);

Another solution - generate string with letters only:

  var length = 9;
  var id = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, length);

Comments

10

For generating random ids, you can also use the standard crypto API with its randomUUID() function which is available in node.js (>=v16.7.0) and all relevant browsers:

const uuid = crypto.randomUUID()
console.log(uuid)
// prints e.g. "7f3f4512-fcf9-45fe-b726-512bba403426"

2 Comments

At the moment of writing this comment, it seems like crypto.randomUUID() doesn't work on Safari iOS. It displays the error message 'crypto.randomUUID is not a function.'
@RomanMahotskyi According to MDN, it is available from Safari iOS 15.4 (Released 2022-03-14).
4

A edited version of @jfriend000 version:

    /**
     * Generates a random string
     * 
     * @param int length_
     * @return string
     */
    function randomString(length_) {

        var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz'.split('');
        if (typeof length_ !== "number") {
            length_ = Math.floor(Math.random() * chars.length_);
        }
        var str = '';
        for (var i = 0; i < length_; i++) {
            str += chars[Math.floor(Math.random() * chars.length)];
        }
        return str;
    }

Comments

4

Or you could use Cripto since it's already built in(except in IE11, I swear these guys havent updated in years!)

https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#Examples

var id = new Uint32Array(10);
window.crypto.getRandomValues(id);

I also found this:

https://gist.github.com/6174/6062387#gistcomment-3255605

let length = 32;
let id = crypto.randomBytes(length).toString("base64");

There's a lot of ways to do this, but for most people, there's no reason to reinvent the wheel :)

Comments

3

I would suggest that you start with some sort of placeholder, you may have this already, but its somewhere to append the div.

<div id="placeholder"></div>

Now, the idea is to dynamically create a new div, with your random id:

var rndId = randomString(8); 
var div = document.createElement('div');
div.id = rndId
div.innerHTML = "Whatever you want the content of your div to be";

this can be apended to your placeholder as follows:

document.getElementById('placeholder').appendChild(div);

You can then use that in your jwplayer code:

jwplayer(rndId).setup(...);

Live example: http://jsfiddle.net/pNYZp/

Sidenote: Im pretty sure id's must start with an alpha character (ie, no numbers) - you might want to change your implementation of randomstring to enforce this rule. (ref)

4 Comments

do i have to worry about the jw player javascript this part in particular jwplayer('placeholder').setup({
@sarsar - I dont follow your question! I just added that part to show you you can re-use the rndId variable in your code to do with setting up jwplayer.
for that jwplayer code i need to place the same id for the div inside this code as well
@sarsar - thats exactly what I demonstrated above. rndId contains the randomly generated code.
2

May I an share an intuitive way to generate a randomID ?

const getRandomID = (length: number) => {
    let text = '';
    const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    for (let i = 0; i < length; i++) {
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    }
    return text;
}

Comments

2

Here is an easy one liner:

const generateUniqueID = (idLength) => [...Array(idLength).keys()].map((elem)=>Math.random().toString(36).substr(2, 1)).join("")

Where all you do is enter the idLength and it will return a unique id of that length.

generateUniqueID(23)
    
>>>'s3y9uebzuo73ih79g0s9p2q' // Id of length 23

Comments

1

First. Assign an id to your div. Like this:

<div id="uniqueid">This text will be replaced</div>

After that, add inside your <script> tag following code:

Document.getElementById("uniqueid").id = randomString(8);

2 Comments

randomString(8) is not defined anywhere.
@David randomString is defined by the person who asked the question. See the original question above.
1

window.btoa(String.fromCharCode(...window.crypto.getRandomValues(new Uint8Array(5))))

Using characters except ASCII letters, digits, '_', '-' and '.' may cause compatibility problems, as they weren't allowed in HTML 4. Though this restriction has been lifted in HTML5, an ID should start with a letter for compatibility.

1 Comment

this brings results that starts with a number, includes + and = chars... may i suggest this flavor: 'id'+window.crypto.getRandomValues(new Uint32Array(1))[0].toString(36)
1
function id(prefix = '', length = 7) {
    let result = prefix;
    for(let i = 0; i < length; i++) {
        const random = Math.random();
        result += String.fromCharCode(Math.floor(random * 26) + (random < .5 ? 65 : 97));
    }
    return result;
}

a random number between 0 and 25 is generated then added to either 65 or 97. When added to 65 it will give you an ascii code for a capital letter and when added to 97, an ascii code for a small letter.

3 Comments

Please explain your code. Code only answers to not very useful
a random number between 0 and 25 is generated then added to either 65 or 97. When added to 65 it will give you an ascii code for a capital letter and when added to 97, an ascii code for a small letter. I hope this helps.
Please edit your answer, don't post in a comment
1

Just use built-int crypto.randomUUID() which is supportted by all major browsers:

let uuid = crypto.randomUUID();
console.log(uuid);

Comments

0

Putting all the great solutions here together:

/** @type {Set<string>} */
const generatedUIDs = new Set();

/**
 * @param {string} [prefix='x'] Prefix all UIDs by string to apply a namespace or ensure starts with [A-Z] character
 * @param {number} [n] Maximum number of variations needed. Calculated as 36^n.
  @return {string} */
function generateUID(prefix = 'x', n = 3) {
  let id;
  while (generatedUIDs.has(id = Math.random().toString(36).slice(2, n + 2)));
  generatedUIDs.add(id);
  return `${prefix}${id}`;
}

Reasoning:

  • Math.random() is not guaranteed to be unique and must be checked against pregenerated values.
  • crypto.randomUUID is not available on 99% of browsers (Safari was last to implement)
  • crypto.randomUUID is much slower than just a Random number
  • Each character is 36 variations. Unlikely to need more than 36^3 (46,656) unique ids/classes on a single DOM page (though you can increase this).

If you want to crypto.randomUUID, you can compress a bit by converting the hexadecimal values (base16) to base 36. Still, you have to prefix to ensure it starts with [A-Z]:

  return `x${crypto.randomUUID().split('-').map((n) => Number.parseInt(n, 16).toString(36)).join('')}`;

This skips the need to build a Set to prevent collisions, but it's still slower and longer than you probably need it to be. Even if Math.random() collides, it's faster to just regenerate.

Perf link

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.