gerar string aleatória para id div

87

Quero exibir vídeos do YouTube em meu site, mas preciso poder adicionar um idvídeo exclusivo para cada vídeo que será compartilhado pelos usuários. Então, juntei tudo e me deparei com um pequeno problema. Estou tentando fazer com que o JavaScript adicione uma string aleatória para o div id, mas não está funcionando, mostrando a 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>
sarsar
fonte
1
Talvez isso seja útil stackoverflow.com/questions/105034/…
Maxx
Normalmente, apenas crio uma var global e a incremento: P
Joseph Marikle
Parece que o OP pode gerar uma string aleatória, mas não pode colocá-la no id do div. Até obter a confirmação, não postarei uma solução.
Jamiec
@Jamiec sim, esse é o meu problema, eu não consigo colocá-lo no ID divs
sarsar
@sarsar - jQuery ou vanilla javascript?
Jamiec

Respostas:

152

Gosto muito desta função:

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

De Criar GUID / UUID em JavaScript?

Joe
fonte
4
... mas não exatamente o problema que ele está perguntando :-)
Soren
171
Mas exatamente o que eu pesquisei no Google: =)
fnkr
6
Aviso: pode criar Guid começando com número. Não é possível usar isso diretamente como id. Id deve começar com _ ou letra. :)
Chaitanya Chandurkar
1
@jbyrd, isso garantirá uma id exclusiva, mas não pode garantir uma id HTMLElement correta . O id do elemento não pode começar com um número. stackoverflow.com/questions/6860853/…
Ihor
1
Para qualquer um que encontrar aqui: Não é assim que os GUIDs reais funcionam, o que pode ser relevante se usado para outra finalidade. Os 13º e 17º dígitos hexadecimais são especiais e precisam ser definidos como 4 e um de {8,9, A, B, C, D}, respectivamente. en.wikipedia.org/wiki/Universally_unique_identifier#Format
The Vee
85

Edição de 2018: acho que esta resposta tem algumas informações interessantes, mas para quaisquer aplicações práticas, você deve usar a resposta de Joe .

Uma maneira simples de criar um ID exclusivo em JavaScript é usar o objeto Date:

var uniqid = Date.now();

Isso dá a você o total de milissegundos decorridos desde 1º de janeiro de 1970, que é um valor único sempre que você chama assim .

O problema com esse valor agora é que você não pode usá-lo como um ID de elemento, pois em HTML, os IDs precisam começar com um caractere alfabético. Também existe o problema de que dois usuários executando uma ação ao mesmo tempo podem resultar no mesmo ID. Poderíamos diminuir a probabilidade disso e corrigir nosso problema de caractere alfabético, acrescentando uma letra aleatória antes da parte numérica do ID.

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

Isso ainda tem uma chance, embora pequena, de colidir. Sua melhor aposta para um id único é manter uma contagem em execução, incrementá-la a cada vez e fazer tudo isso em um único lugar, ou seja, no servidor.

Alex Turpin
fonte
5
As datas em si não são muito aleatórias, pois dois usuários que fazem a mesma operação ao mesmo tempo podem obter o mesmo valor de data. Se você combinar uma data com uma função de número aleatório, obterá algo muito mais exclusivo.
jfriend00
Além disso, a valueOfrepresentação é um número, que não é um id html válido (eles precisam começar com um caractere alfa)
Jamiec
3
@Chris minha resposta não foi factualmente incorreta, simplesmente não foi a melhor das respostas aqui. Eu adicionei algumas coisas.
Alex Turpin
6
Collide: var arr = [Date.now(), Date.now()];. Fácil de reproduzir em CPUs modernas.
mostruash de
2
Esta é uma solução muito ruim para o problema de qualquer tipo de geração de Id, em particular para a questão real que está sendo colocada (sugerindo que a questão não foi lida). É muito provável que você termine com o mesmo id para dois divs (um milissegundo é muito tempo). A resposta de @ jfriend00 é muito melhor (em particular a "Outra maneira de fazer"). Se você deseja obter IDs que provavelmente não colidem globalmente, então um monte de alfanum aleatórios são muito melhores - ou apenas vá para GUIDs (UUIDs) como 'Joe' sugere.
stolsvik
74

Aqui está a função reutilizável para gerar os IDs aleatórios:

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

// Não começará com nenhum dígito, portanto, será compatível com CSS3

bvmCoder
fonte
Isso poderia resultar em uma string vazia, que não seria um ID válido. var lengths = {}, total = 1000000; for(var i = 0; i < total; i++){ var newLength = revisedRandId().length; lengths[newLength] = (lengths[newLength] || 0) + 1; } lengths[0] / total- parece que forneceria um ID inválido em cerca de 0,03% das vezes, portanto, não com frequência, mas definitivamente possível.
1j01
Por que você descarta os primeiros 2 dígitos?
Fábio
Math.random().toString(36)-> "0.v6doivsvnkg". Descartar os primeiros dois caracteres é redundante, pois eles são removidos com o comando replace: Math.random().toString(36).replace(/[^a-z]+/g, '')-> "vdoivsvnkg".
Ivan Kovtun
30

Acho que algumas pessoas aqui não se concentraram realmente em sua pergunta em particular. Parece que o problema que você tem é colocar o número aleatório na página e conectar o jogador a ele. Existem várias maneiras de fazer isso. O mais simples é com uma pequena mudança em seu código existente como esta para document.write () o resultado na página. Eu normalmente não recomendaria document.write (), mas como seu código já está embutido e o que você estava tentando fazer era colocar o div embutido, esta é a maneira mais simples de fazer isso. No ponto em que você tem o número aleatório, basta usá-lo para colocá-lo e o div na página:

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

e então, você se refere a isso no código de configuração do jwplayer como este:

jwplayer(randomId).setup({

E todo o bloco de código ficaria assim:

<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>

Outra maneira de fazer isso

Posso acrescentar aqui no final que gerar um número verdadeiramente aleatório apenas para criar um ID div único é um exagero. Você não precisa de um número aleatório. Você só precisa de um ID que, de outra forma, não existirá na página. Frameworks como o YUI têm essa função e tudo o que fazem é ter uma variável global que é incrementada cada vez que a função é chamada e então combiná-la com uma string de base única. Pode ser parecido com isto:

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

E, então, em uso prático, você faria algo assim:

var randomId = generateID("myMovieContainer");  // "myMovieContainer1"
document.write('<div id="' + randomId + '">This text will be replaced</div>');
jwplayer(randomId).setup({
jfriend00
fonte
Esta resposta também é boa, mas presumo que dentro desse jwplayercódigo divnão deveria estar 'div()'.
Jamiec
@ jfriend00 Jamiec está certo, eu preciso ser capaz de combinar o ID do div com o código do jogador jw aquijwplayer('div').setup({
sarsar
Sim, eu não tinha ideia do que o código jwplayer estava fazendo ou como funcionava. Eu não sabia que isso era parte da questão. De qualquer forma, eu pesquisei isso na web e modifiquei meu código para que o div com o número aleatório ID seja passado para a configuração do jwplayer também. Para sua informação, como os IDs CSS não podem, tecnicamente, começar com um dígito, também coloco uma letra no início.
jfriend00
Eu adicionei uma maneira um pouco mais simples de fazer isso no final da minha resposta. Um número aleatório não é realmente necessário neste caso, apenas um número monotomicamente crescente combinado com uma string de base única.
jfriend00
Se você precisar de exclusividade entre os arquivos, um ID aleatório pode ser garantido.
aleclarson de
17

Eu também precisava de um ID aleatório, usei a codificação base64:

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

Escolha quantos caracteres quiser, o resultado geralmente é de pelo menos 24 caracteres.

Staale
fonte
13

Com base no HTML 4 , o id deve começar da letra:

Os tokens de ID e NOME devem começar com uma letra ([A-Za-z]) e podem ser seguidos por qualquer número de letras, dígitos ([0-9]), hifens ("-"), sublinhados ("_") , dois pontos (":") e pontos (".").

Portanto, uma das soluções pode ser (alfanumérica):

  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);

Outra solução - gere string apenas com letras:

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

eu gosto deste simples:

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

já que o id deve (embora não deva) começar com uma letra, eu o usaria assim:

let div_id = randstr('youtube_div_');

alguns valores de exemplo:

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
Oriadam
fonte
4

Uma versão editada da versão @ jfriend000:

    /**
     * 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;
    }
cara
fonte
2

Eu sugiro que você comece com algum tipo de espaço reservado, você já pode ter isso, mas é um lugar para adicionar o div.

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

Agora, a ideia é criar dinamicamente um novo div, com seu id aleatório:

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

isso pode ser anexado ao seu marcador da seguinte forma:

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

Você pode então usar isso em seu código jwplayer:

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

Exemplo ao vivo: http://jsfiddle.net/pNYZp/

Nota secundária: Tenho certeza de que os ids devem começar com um caractere alfa (ou seja, sem números) - você pode querer alterar sua implementação de randomstring para aplicar esta regra. ( ref )

Jamiec
fonte
tenho que me preocupar com o jw player javascript esta parte em particularjwplayer('placeholder').setup({
sarsar
@sarsar - Não entendi sua pergunta! Acabei de adicionar essa parte para mostrar que você pode reutilizar a rndIdvariável em seu código para configurar o jwplayer.
Jamiec
para esse código jwplayer eu preciso colocar o mesmo id para o div dentro deste código também
sarsar
@sarsar - isso é exatamente o que demonstrei acima. rndIdcontém o código gerado aleatoriamente.
Jamiec
1

Ou você pode usar o Cripto, pois já está integrado (exceto no IE11, juro que esses caras não atualizam há anos!)

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

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

Eu também encontrei este:

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

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

Há muitas maneiras de fazer isso, mas para a maioria das pessoas, não há razão para reinventar a roda :)

Jaacko Torus
fonte
0

Primeiro. Atribua um id ao seu div. Como isso:

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

Depois disso, adicione dentro de sua <script>tag o seguinte código:

Document.getElementById("uniqueid").id = randomString(8);
Vsushkov
fonte
6
randomString(8)não está definido em qualquer lugar.
Ethan
3
@David randomString é definido pela pessoa que fez a pergunta. Veja a pergunta original acima.
vsushkov
0

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

Usando caracteres, exceto letras ASCII, dígitos, '_', '-' e '.' podem causar problemas de compatibilidade, pois não eram permitidos no HTML 4. Embora essa restrição tenha sido suspensa no HTML5, um ID deve começar com uma carta de compatibilidade.

Denis Giffeler
fonte
isso traz resultados que começam com um número, inclui +e =chars ... posso sugerir este sabor:'id'+window.crypto.getRandomValues(new Uint32Array(1))[0].toString(36)
oriadam