用javascript创build唯一的ID

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

更新:这里是select城市的forms的一部分。 另外请注意,我正在使用一些PHP来填写特定状态时select的城市。

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

你能不能保持一个跑步指数?

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

编辑

经过进一步的考虑,你实际上可能更喜欢使用数组样式的名称来select…

例如

 <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方法dynamic创build选项可以按如下方式完成:

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

假设citiesarrays已经存在

或者,您可以使用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; 

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

 var uniq = 'id' + (new Date()).getTime(); 
 var id = "id" + Math.random().toString(16).slice(2) 
 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); } 

非常短的function会给你唯一的ID:

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

alert(uid());

回复@scott:有的时候JS走得很快,所以…

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

在你的名字空间中放入一个类似于下面的实例

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

我正在处理与OP类似的问题,并发现@Guy和@Scott解决scheme的元素可以结合起来,创build出更加坚实的IMO解决scheme。 这里生成的唯一ID有三个由下划线分开的部分:

  1. 领导信
  2. 以36为底的时间戳;
  3. 最后,随机部分。

这个解决scheme应该工作得很好,即使是非常大的集合:

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

为了避免创build任何计数器,并确保该id是唯一的,即使有一些其他组件可以在页面上创build带有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 

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

这里有一个函数(函数genID()下面),根据你想要的任何id的优先级/ IDrecursion地检查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; } } 

这是我自己的基于创build的元素的xpath:

 /** Returns the XPATH of an element **/ var getPathTo = function(element) { if (element===document.body) return element.tagName; var ix= 0; var siblings= element.parentNode.childNodes; for (var i= 0; i<siblings.length; i++) { var sibling= siblings[i]; if (sibling===element) // stripped xpath (parent xpath + tagname + index) return getPathTo(element.parentNode)+ element.tagName + ix+1; if (sibling.nodeType===1 && sibling.tagName===element.tagName) ix++; } } /** hashcode function (credit http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery **/ var hashCode = function(str) { var hash = 0, i, chr, len; if (str.length === 0) return hash; for (i = 0, len = str.length; i < len; i++) { chr = str.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; // Convert to 32bit integer } return hash; }; /** Genaretes according to xpath + timestamp **/ var generateUID = function(ele) { return hashCode(getPathTo(ele)) + new Date().getTime(); } 

首先获取元素的xpath。

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

这里的问题是,如果在运行中生成了独特的元素,那么xpath并不是唯一唯一的。 因此我们在最后添加时间戳。

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

你可以利用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() ,但更容易阅读。

您可以使用计时器生成一个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! 
 .as-console-wrapper{border-top: none !important;overflow-y: auto !important;top: 0;} 

我使用如下的函数:

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

在参数baseId我指出id的前缀更容易识别元素。