最初的 Q 对内容/目的不是很具体,应该有变化,这取决于 IMO。在某一点上,我绝对不同意当前接受的答案。循环并附加新的 ID 到大量已经渲染的 HTML 可能会导致大量的回流计算,这可能会变得丑陋,具体取决于“stuffContainer”代表什么。
如果必须,首先从服务器使用 ID 构建或在客户端作为单个块注入
作为一般规则,如果可以避免,请避免重复更改 DOM。就加载页面的浏览器 IMO 而言,预先在服务器上构建的 ID 可以忽略不计。当然,它是一个更大的,因此更慢的哈希表,但如果我们谈论的是数百而不是数万,我严重怀疑你会注意到。
对于从数据构建的选择列表之类的情况,一种更有效的客户端方法是首先构建为字符串,带有 ID 和所有内容,然后分配给容器的 innerHTML,或者像我的一些 js 聊天同事一样,您在每个可能的用例中都有一个关于 innerHTML 的奇怪挂断,即使它现在在规范中,至少首先构建并附加到文档片段。然后将其附加到您的容器中。
ID 上的数据属性或类
IMO,气味因素与性能无关,而是 HTML 膨胀和创建不需要的 ID 依赖项,从而阻止其他可能在您的单个项目 div 上找到自定义 ID 有用的东西。ID 绝对是缩小 JavaScript 中元素查找范围的理想方式,但在容器包含内容的情况下,您将从 ID 容器中获得比 ID 为每个子项 ID 更大的灵活性。单步与两步的性能增益不值得将通用 ID 应用于元素的灵活性成本。
作为替代方案,您可以使用具有唯一值或数据属性的类,例如'data-itemId="0"'。对于较小的 HTML 集,例如自定义选择列表,其中 ID 连接到某些服务器端索引系统以便于更新数据,我倾向于使用这种高度可见的方法,因为它更容易理解架构,但它增加了很多在可能涉及数百到数千个项目的情况下跟踪不必要的属性。
或者理想情况下(在大多数情况下),事件委托
最理想的是,IMO,如果您只关心您单击的子单项元素而不是它的“ID”或这些单项容器将保持静态的顺序,您可以安全地避免使用其他属性假设职位是有效的 ID。或者,这可能适用于非静态单项集的另一种情况是,如果您在一组对象中获得单项数据,这些对象会被打乱,然后用于在用户启动的排序上构建和替换 HTML,这些排序总是将 HTML 的顺序与其他数据跟踪依赖项联系起来。
非 Jquery 方法(未经测试):
var myContainer = document.getElementById('stuffContainer');
//ignore following indent goof
myContainer.addEventListener('click', function(e){
var
singleItem,
elementOriginallyClicked = singleItem = e.target,
stuffContainer = this;
//anything clicked inside myContainer will trigger a click event on myContainer
//the original element clicked is e.target
//google 'event bubbling javascript' or 'event delegation javascript' for more info
//climb parentNodes until we get to a single-item node
//unless it's already single-item that was originally clicked
while( !singleItem.className.match(/[=\s'"]single-item[\s'"]/g) ){
singleItem = singleItem.parentNode;
}
//You now have a reference to the element you care about
//If you want the index:
//Get the singleItem's parent's childNodes collection and convert to array
//then use indexOf (MDN has normalizer for IE<=8) to get the index of the single-item
var childArray = Array.prototype.slice.apply(stuffContainer.childNodes,[0]),
thisIndex = childArray.indexOf(singleItem);
doSomethingWithIndex(thisIndex);
//or
//doSomethingWithDOMObject(singleItem);
} );
或简单的 JQuery 委托样式(也未经测试):
$('#someContainer').on('click','.single-item', function(){
var $_singleItem = $(this), //jq handles the bubble to the interesting node for you
thisIndex = $_singleItem.index(); //also getting index relative to parent
doSomethingWithIndex(thisIndex);
//or
//doSomethingWithJQObject($_thisItem);
} );