使用javascript创建唯一ID

Jam*_*ett 45 html javascript select dynamic

我有一个表单,用户可以为多个城市添加多个选择框.问题是每个新生成的选择框都需要具有唯一的ID.可以这样做是JavaScript吗?

更新:这是选择城市的表格的一部分.另请注意,当选择特定状态时,我正在使用一些php来填充城市.

<form id="form" name="form" method="post" action="citySelect.php">
<select id="state" name="state" onchange="getCity()">
    <option></option>
    <option value="1">cali</option>
    <option value="2">arizona</option>
    <option value="3">texas</option>
</select>
<select id="city" name="city" style="width:100px">

</select>

    <br/>
</form>
Run Code Online (Sandbox Code Playgroud)

这是javascript:

$("#bt").click(function() {

$("#form").append(
       "<select id='state' name='state' onchange='getCity()'>
           <option></option>
           <option value='1'>cali</option>
           <option value='2'>arizona</option>
           <option value='3'>texas</option>
        </select>
        <select id='city' name='city' style='width:100px'></select><br/>"
     );
});
Run Code Online (Sandbox Code Playgroud)

Sco*_*den 38

它使用毫秒计时器的另一种方式:

var uniq = 'id' + (new Date()).getTime();
Run Code Online (Sandbox Code Playgroud)

  • 如果用户在不同的国家/地区创建 ID,会发生什么情况?\ (4认同)
  • 如果你一个接一个地创建2个id,它将不会是独一无二的.`var first =(new Date()).getTime(); var second =(new Date()).getTime(); console.log(first == second);` (4认同)
  • @UlysseBN 刚刚尝试了“performance.now()”,尽管具有超高分辨率,但它在我的机器上无法按照您所描述的那样工作。 (4认同)
  • 似乎不是一个好主意`(+新日期+ +新日期)/ 2 === +新日期;` (2认同)

小智 35

const uid = function(){
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
}
Run Code Online (Sandbox Code Playgroud)

此函数生成非常独特的 ID,按其生成日期排序。也可用于数据库中的 ID。

  • 不错,也许稍微改变一下就能固定长度: `Date.now().toString(36) + Math.floor(Math.pow(10, 12) + Math.random() * 9*Math.pow( 10, 12)).toString(36)` (5认同)
  • 请注意它可以有不同的长度 (3认同)
  • 很好的建议,但您可能想用“substring”或“slice”替换已弃用的“substr”,以确保它在大多数环境中都有效。请参阅 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring#the_difference_ Between_substring_and_substr (2认同)
  • @Aditya 不幸的是,这还没有解决。在循环中运行它显示它在字符串长度 16 和 17 之间交替作为输出。 (2认同)

小智 35

最短且无库,也适用于nodejs

crypto.randomUUID();
// 'a63ae209-ec69-4867-af8a-6f4d1efe15c6'
Run Code Online (Sandbox Code Playgroud)

https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID

crypto.randomUUID();
// 'a63ae209-ec69-4867-af8a-6f4d1efe15c6'
Run Code Online (Sandbox Code Playgroud)
btn.onclick = () => myID.textContent = crypto.randomUUID()
Run Code Online (Sandbox Code Playgroud)

  • 您应该提到“chrome &gt; 92”并且仅在“HTTPS”中 (3认同)

Fab*_*olo 34

var id = "id" + Math.random().toString(16).slice(2)
Run Code Online (Sandbox Code Playgroud)

  • 虽然远程碰撞的概率不是空的 (4认同)

Jon*_*and 20

你能不能保持一个正在运行的指数?

var _selectIndex = 0;

...code...
var newSelectBox = document.createElement("select");
newSelectBox.setAttribute("id","select-"+_selectIndex++);
Run Code Online (Sandbox Code Playgroud)

编辑

经过进一步考虑,您可能更愿意为您的选择使用数组样式名称...

例如

<select name="city[]"><option ..../></select>
<select name="city[]"><option ..../></select>
<select name="city[]"><option ..../></select>
Run Code Online (Sandbox Code Playgroud)

然后,在php的服务器端,例如:

$cities = $_POST['city']; //array of option values from selects
Run Code Online (Sandbox Code Playgroud)

编辑2回应OP评论

使用DOM方法动态创建选项可以按如下方式完成:

var newSelectBox = document.createElement("select");
newSelectBox.setAttribute("id","select-"+_selectIndex++);

var city = null,city_opt=null;
for (var i=0, len=cities.length; i< len; i++) {
    city = cities[i];
    var city_opt = document.createElement("option");
    city_opt.setAttribute("value",city);
    city_opt.appendChild(document.createTextNode(city));
    newSelectBox.appendChild(city_opt);
}
document.getElementById("example_element").appendChild(newSelectBox);
Run Code Online (Sandbox Code Playgroud)

假设cities数组已经存在

或者你可以使用innerHTML方法.....

var newSelectBox = document.createElement("select");
newSelectBox.setAttribute("id","select-"+_selectIndex++);
document.getElementById("example_element").appendChild(newSelectBox);

var city = null,htmlStr="";
for (var i=0, len=cities.length; i< len; i++) {
    city = cities[i];
    htmlStr += "<option value='" + city + "'>" + city + "</option>";
}
newSelectBox.innerHTML = htmlStr;
Run Code Online (Sandbox Code Playgroud)


小智 19

function uniqueid(){
    // always start with a letter (for DOM friendlyness)
    var idstr=String.fromCharCode(Math.floor((Math.random()*25)+65));
    do {                
        // between numbers and characters (48 is 0 and 90 is Z (42-48 = 90)
        var ascicode=Math.floor((Math.random()*42)+48);
        if (ascicode<58 || ascicode>64){
            // exclude all chars between : (58) and @ (64)
            idstr+=String.fromCharCode(ascicode);    
        }                
    } while (idstr.length<32);

    return (idstr);
}
Run Code Online (Sandbox Code Playgroud)

  • 为了OP的利益,你可能想解释你的答案 (2认同)
  • 为了笑,我决定看看它有多大可能:var meh = fun(); while(meh!== fun()){console.log('.'); 在Chrome的命令行中...到目前为止它已经有一百万没有重复,对于大多数情况你可以拥有这个绰绰有余.我猜想有32个字符长度. (2认同)

Sak*_* B. 16

不需要外部库。证明了唯一性。

你可以做这样的事情。

// Function to generate unique id

const uniqueId = (length=16) => {
  return parseInt(Math.ceil(Math.random() * Date.now()).toPrecision(length).toString().replace(".", ""))
}

// ----------------------------

document.querySelector("#butt01").onclick = () => {
  document.querySelector("#span01").innerHTML = uniqueId()
}

ids = new Set()
count = 0

document.querySelector("#butt02").onclick = () => {
  for (let i = 0; i< 1000; i++){
    ids.add(uniqueId())
  }

  document.querySelector("#span02").innerHTML = `Found ${1000 - ids.size} duplicated random values.`
}
Run Code Online (Sandbox Code Playgroud)
<div>
    <button id="butt01">Generate</button>
    <span id="span01"></span>
    <hr>
    <button id="butt02">Check collision potentiality in 1000 cases</button>
    <span id="span02"></span>
</div>
Run Code Online (Sandbox Code Playgroud)

将自纪元以来的时间(以毫秒为单位)与随机值乘以固定大小。

运行此命令以查看可能的冲突。

您会看到无论是 1000、10000 还是 1000000000,都没有冲突。

如果两个用户同时生成 id 并获得相同的随机数,那么这种情况的可能性很小。

为了增加唯一性,您可以将 date 更多Math.random()s 相乘。


Jun*_*ari 11

很短的功能会给你唯一的ID:

var uid = (function(){var id=0;return function(){if(arguments[0]===0)id=0;return id++;}})();
Run Code Online (Sandbox Code Playgroud)

alert(uid());

  • 如果巧合碰巧在页面上已经有一个具有下一个id的元素,则会失败. (2认同)

mol*_*oco 10

回复@scott:有时JS走得很快......所以......

var uniqueId = null,
    getUniqueName = function(prefix) {
        if (!uniqueId) uniqueId = (new Date()).getTime();
        return (prefix || 'id') + (uniqueId++);
    };
Run Code Online (Sandbox Code Playgroud)

  • 除非错误,只会检查一次重复? (6认同)
  • 它不检查重复项,而是递增最后一个数值。 (2认同)
  • 顺便说一句,您是否立即设置了初始的“uniqueId”,您将不需要条件。 (2认同)

Uly*_* BN 9

您可以使用计时器生成 ID使用以下方法避免重复performance.now()

id = 'id' + performance.now()
dup = 'id' + performance.now()

console.log(id)
console.log(id.replace('.','')) // sexy id
console.log(id === dup) // false!
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper{border-top: none !important;overflow-y: auto !important;top: 0;}
Run Code Online (Sandbox Code Playgroud)

请注意,高分辨率时间 API 在所有最新浏览器中均可用


编辑(根据西普里安的评论):不幸的是,这还不够,performance.now()只能精确到毫秒。考虑将其与以下内容结合使用Math.random()

const generateId = () => `${performance.now()}${Math.random().toString().slice(5)}`.replace('.','')

let id = generateId()
let dup = generateId()

console.log(id)
console.log(id === dup) // false!

let ary = [...Array(1000)].map(_ => generateId())
console.log((new Set(ary)).size === 1000) // no dups!
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper{border-top: none !important;overflow-y: auto !important;top: 0;}
Run Code Online (Sandbox Code Playgroud)


fed*_*ghe 6

在您的命名空间中放入一个类似于以下实例的实例

var myns = {/*.....*/};
myns.uid = new function () {
    var u = 0;
    this.toString = function () {
        return 'myID_' + u++;
    };
};
console.dir([myns.uid, myns.uid, myns.uid]);
Run Code Online (Sandbox Code Playgroud)


yod*_*mok 6

我正在为OP做类似的问题,并发现@Guy和@Scott的解决方案的元素可以结合起来创建一个更加稳固的IMO解决方案.由此产生的唯一ID包含由下划线分隔的三个部分:

  1. 一封领先的信;
  2. 基数36中显示的时间戳;
  3. 最后一个随机的部分.

这个解决方案应该可以很好地工作,即使是非常大的集合:

function uniqueId () {
    // desired length of Id
    var idStrLen = 32;
    // always start with a letter -- base 36 makes for a nice shortcut
    var idStr = (Math.floor((Math.random() * 25)) + 10).toString(36) + "_";
    // add a timestamp in milliseconds (base 36 again) as the base
    idStr += (new Date()).getTime().toString(36) + "_";
    // similar to above, complete the Id using random, alphanumeric characters
    do {
        idStr += (Math.floor((Math.random() * 35))).toString(36);
    } while (idStr.length < idStrLen);

    return (idStr);
}
Run Code Online (Sandbox Code Playgroud)


Asa*_*af 5

您可以使用 ES6 中引入的 Generator 函数(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*

const idCreator = function*() {
  let i = 0;
  while (true) yield i++;
};

const idsGenerator = idCreator();
const generateId = () => idsGenerator.next().value;

console.log(generateId()) // 0
console.log(generateId()) // 1
console.log(generateId()) // 2
Run Code Online (Sandbox Code Playgroud)