使用javascript创建唯一ID

时间:2010-07-12 19:12:13

标签: javascript html select dynamic

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

更新:这是选择城市的表格的一部分。另请注意,当选择特定状态时,我正在使用一些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>

这是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/>"
     );
});

29 个答案:

答案 0 :(得分:37)

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

var uniq = 'id' + (new Date()).getTime();

答案 1 :(得分:32)

var id = "id" + Math.random().toString(16).slice(2)

答案 2 :(得分:20)

你能不能保持一个正在运行的索引?

var _selectIndex = 0;

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

修改

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

e.g。

<select name="city[]"><option ..../></select>
<select name="city[]"><option ..../></select>
<select name="city[]"><option ..../></select>

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

$cities = $_POST['city']; //array of option values from selects

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

假设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;

答案 3 :(得分: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);
}

答案 4 :(得分:11)

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

var uid = (function(){var id=0;return function(){if(arguments[0]===0)id=0;return id++;}})();
  

alert(uid());

答案 5 :(得分:9)

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

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

答案 6 :(得分:6)

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

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

答案 7 :(得分:5)

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

  1. 一封领先的信;
  2. 在基数36中显示的时间戳;
  3. 最后的随机部分。
  4. 这个解决方案应该可以很好地工作,即使是非常大的集合:

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

答案 8 :(得分:2)

为避免创建任何计数器并确保id是唯一的,即使有一些其他组件在页面上创建带有id的元素,您也可以使用随机数,如果它不好则更正足够(但你必须立即设置id以避免冲突):

var id = "item"+(new Date()).getMilliseconds()+Math.floor(Math.random()*1000);
 // or use any random number generator
 // whatever prefix can be used instead of "item"
while(document.getElementById(id))
    id += 1;
//# set id right here so that no element can get that id between the check and setting it

答案 9 :(得分:1)

不需要外部库。证明了独特性。

您可以这样做。

// 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 = []
count = 0
document.querySelector("#butt02").onclick = () => {
  for (let i = 0; i< 1000; i++){
    ids.push(uniqueId())
  }
  for (el of ids){
    for (ell of ids){
      if(el == ell && ids.indexOf(el) != ids.indexOf(ell)){
        count += 1
      }
    }
  }
  document.querySelector("#span02").innerHTML = `Found ${count} duplicated random values.`
}
<button id="butt01">Generate</button>
<br>
<span id="span01"></span>
<br>
<hr>
<br>
<button id="butt02">Check collision potentiality in 1000 cases</button>
<br>
<span id="span02"></span>

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

运行此命令以查看可能发生的碰撞。

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

如果两个用户同时生成id并获得rame随机数,则机会很小。

要增加唯一性,您可以将日期多Math.random()乘以一个日期。

答案 10 :(得分:1)

function generateId() {
       
return Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);
       
    
}

console.log(generateId())

答案 11 :(得分:1)

随机性是 不是 唯一的。时间值是 不是 唯一的。概念是完全不同的,并且在您的应用程序扩展和分发时,差异会变得丑陋。上面的许多答案都有潜在的危险。

一种更安全的解决发帖人问题的方法是使用UUID:Create GUID / UUID in JavaScript?

答案 12 :(得分:1)

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

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

答案 13 :(得分:1)

看看这个小小的美丽,这将完成您的工作。

function (length) {
    var id = '';
    do { id += Math.random().toString(36).substr(2); } while (id.length < length);
    return id.substr(0, length);
}

答案 14 :(得分:1)

警告:这个答案可能对此问题的一般意图不利,但我在此发布,因为它解决了此问题的部分版本。

您可以使用lodash&#39; uniqueId(文档here)。这不是一个很好的uniqueId生成器,例如db记录,或者会在浏览器中持久保存会话的东西。但是我来这里寻找这个的原因是通过使用它来解决的。如果你需要一个足够瞬态的唯一id,那就可以了。

我需要它,因为我正在创建一个可重复使用的反应组件,它具有标签和表单控件。标签需要具有for="controlId"属性,对应于实际表单控件具有的id="controlId"(输入或选择元素)。在此上下文中不需要此id,但我需要为要共享的两个属性生成一个id,并确保此ID在呈现的页面的上下文中是唯一的。所以lodash的功能运作得很好。以防万一对其他人有用。

答案 15 :(得分:1)

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

&#13;
&#13;
id = 'id' + performance.now()
dup = 'id' + performance.now()

console.log(id)
console.log(id.replace('.','')) // sexy id
console.log(id === dup) // false!
&#13;
.as-console-wrapper{border-top: none !important;overflow-y: auto !important;top: 0;}
&#13;
&#13;
&#13;

请注意High resolution time API is available in all recent browsers

答案 16 :(得分:1)

有两个可用的软件包。

  • 用于简短的唯一ID生成nanoid link
import { nanoid } from 'nanoid'
const id = nanoid()    // "Uakgb_J5m9g-0JDMbcJqLJ"
const id = nanoid(10)  // "jcNqc0UAWK"
  • 用于通用唯一ID生成uuid link
import { v4 as uuidv4 } from 'uuid';
const id= uuidv4();    // quite big id

答案 17 :(得分:1)

这是一个函数(下面的函数genID()),它根据你想要的id prefex / ID递归地检查DOM的唯一性。

在你的情况下,你可能会这样使用它

var seedNum = 1;
newSelectBox.setAttribute("id",genID('state-',seedNum));

function genID(myKey, seedNum){
     var key = myKey + seedNum;
     if (document.getElementById(key) != null){
         return genID(myKey, ++seedNum);
     }
     else{
         return key;
     }
 }

答案 18 :(得分:1)

像其他人一样说你可以使用正在运行的索引,或者如果你不喜欢使用变量的想法,只需拉出列表中最后一个城市的id并在其id中加1。

答案 19 :(得分:0)

用于生成唯一ID:

const uid = () =>
  String(
    Date.now().toString(32) +
      Math.random().toString(32) +
      Math.random().toString(32)
  ).replace(/\./g, '')

检查是否有效:

var size = 500000
var arr = new Array(size)
  .fill(0)
  .map(() => uid())

var b = new Set(arr)

console.log(
  size === b.size ? 'all ids are unique' : `not unique records ${size - b.size}`
)

答案 20 :(得分:0)

可以使用 Generator 函数,在 ES6 (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
...

答案 21 :(得分:0)

我认为,如果您真的想拥有唯一ID ,那么最好的方法是使用类似以下的库:
uuiduniqueid

注意唯一ID 随机ID

仅使用日期时间毫秒方法是错误的。
如今,计算机已经足够快,能够在一毫秒内运行一次以上的循环迭代。

npm install uuid

导入库:

如果您正在使用ES模块

import { v4 as uuidv4 } from 'uuid';

对于CommonJS:

const { v4: uuidv4 } = require('uuid');

用法

uuidv4();

// This will output something like: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d

答案 22 :(得分:0)

    const generateUniqueId = () => 'id_' + Date.now() + String(Math.random()).substr(2);

    // if u want to check for collision
    const arr = [];
    const checkForCollision = () => {
      for (let i = 0; i < 10000; i++) {
        const el = generateUniqueId();
        if (arr.indexOf(el) > -1) {
          alert('COLLISION FOUND');
        }
        arr.push(el);
      }
    };

答案 23 :(得分:0)

以毫秒为单位的随机和日期相结合应该可以使冲突几乎没有变化:

function uniqid(){
  return Math.random().toString(16).slice(2)+(new Date()).getTime()+Math.random().toString(16).slice(2);
}
alert(uniqid()+"\r"+uniqid());

答案 24 :(得分:0)

我使用如下函数:

function (baseId) {
  return baseId + '-' + Math.random().toString(16).slice(2);
}

在参数baseId中,我指示id的前缀,以便更容易识别元素。

答案 25 :(得分:0)

您可以利用closure

var i = 0;
function generateId() {
    return i++;
}

如果你想把它括起来:

function generator() {
  var i = 0;
  return function() {
    return i++;
  };
}

var generateId = generator();
generateId(); //1
generateId(); //2

generator可以接受默认前缀; generateId coud接受可选后缀:

function generator(prefix) {
  var i = 0;
  return function(suffix) {
    return prefix + (i++) + (suffix || '');
  };
}

var generateId = generator('_');
generateId('_'); //_1_
generateId('@'); //_2@

如果您希望自己的ID指示序列,非常类似new Date().getTime(),但更容易阅读,这会派上用场。

答案 26 :(得分:0)

根据创建的元素的xpath,我自己采取了这个方法:

label.transform = CGAffineTransformInvert(containerView.transform)

首先获取元素的xpath。

然后计算xpath的哈希码。因此,每个xpath都有一个唯一的id。

这里的问题是,如果在运行中生成唯一元素,则xpath不是必需的唯一。因此,我们在最后添加时间戳。

也许我们还可以通过添加最终的Math.Random()来保证更多的独特元素。

答案 27 :(得分:-1)

简单解决方案:)

const ID = (_length=13) => {
  // Math.random to base 36 (numbers, letters),
  // grab the first 9 characters
  // after the decimal.
  return '_' + Math.random().toString(36).substr(2, _length); // max _length should be less then 13
};
console.log("Example ID()::", ID())

答案 28 :(得分:-1)

let transactionId = ${new Date().getDate()}${new Date().getHours()}${new Date().getSeconds()}${new Date().getMilliseconds()}

let transactionId =`${new Date().getDate()}${new Date().getHours()}${new Date().getSeconds()}${new Date().getMilliseconds()}` 

console.log(transactionId)