我有一个表单,用户可以为多个城市添加多个选择框。问题是每个新生成的选择框都需要具有唯一的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/>"
);
});
答案 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有三个以下划线分隔的部分:
这个解决方案应该可以很好地工作,即使是非常大的集合:
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()
避免重复:
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;
请注意High resolution time API is available in all recent browsers。
答案 16 :(得分:1)
有两个可用的软件包。
nanoid
link import { nanoid } from 'nanoid'
const id = nanoid() // "Uakgb_J5m9g-0JDMbcJqLJ"
const id = nanoid(10) // "jcNqc0UAWK"
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 ,那么最好的方法是使用类似以下的库:
uuid或uniqueid
注意:唯一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)