用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);
假设cities
arrays已经存在
或者,您可以使用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有三个由下划线分开的部分:
- 领导信
- 以36为底的时间戳;
- 最后,随机部分。
这个解决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的前缀更容易识别元素。