意见:在HTML中,可能有重复的ID或者非标准属性吗?
希望让JavaScript知道特定的dom节点与数据库中的记录相对应,这似乎很常见。你是怎么做到的?
我已经看到的一种很常见的方式是对类型使用一个类,对ID使用一个ID:
<div class="thing" id="5"> <script> myThing = select(".thing#5") </script>
但是,这存在一些html标准问题-如果页面上的记录类型不止一种,则最终可能会重复生成ID。但这并没有什么不好的,不是吗?
一种替代方法是使用数据属性:
<div data-thing-id="5"> <script> myThing = select("[data-thing-id=5]") </script>
这可以解决重复的ID问题,但这确实意味着我们必须处理属性而不是ID,这有时会更加困难。你们有什么感想?
解决方案
<div class="thing" id="myapp-thing-5"/> // Get thing on the page for a particular ID var myThing = select("#myapp-thing-5"); // Get ID for the first thing on the page var thing_id = /myapp-thing-(\d+)/.exec ($('.thing')[0].id)[1];
考虑到每个元素可以有多个类,我们是否不能创建一个唯一标识符作为每个元素的添加类?这样,可能会有多个具有相同" id"的元素,而没有HTML ID属性冲突。
<div class="thing myapp-thing-5" /> <div class="thing myapp-thing-668" /> <div class="thing myapp-thing-5" />
然后很容易找到这些节点,并通过少量的字符串操作即可找到它们对应的数据库记录。
我们将放弃对DOM的某些控制
没错,什么都不会爆炸,但这是错误的做法。如果在页面上放置重复的ID,则基本上会失去在尝试通过其ID访问元素时确定要获取的内容的能力。
var whoKnows = document.getElementById('duplicateId');
实际上,行为是不同的,具体取决于浏览器。无论如何,我们都可以将classNames用于重复的值,并且完全可以避免该问题。
浏览器将尝试忽略标记中的错误,但情况变得凌乱且更加困难。最好的办法是保持标记有效。我们可以在className中描述元素的类型及其唯一的数据库ID。我们甚至可以使用多个className来区分它们。有很多有效的可能性:
<div class="friend04"/> <div class="featuredFriend04" />
或者
<div class="friend friend04" /> <div class="featuredFriend friend04" />
或者
<div class="friend objectId04" /> <div class="groupMember objectId04" />
或者
<div class="friend objectId04" /> <div class="friend objectId04" id="featured" />
这些都是XHTML的完全合法和有效的摘要。请注意,在最后一小段中,我仍然有一个id对我有用,这很好。通过它们的id访问元素非常快速且容易,因此我们绝对希望能够在可能的情况下利用它。
我们已经在JavaScript上花费了足够的时间,以确保我们拥有正确的值和类型。在页面上放置重复的ID只会使工作更加困难。如果我们找到了编写符合标准的标记的方法,那么它将具有许多实际好处。
如果使用XHTML并花时间扩展用于覆盖新属性的DTD,则非标准属性很好。就个人而言,就像其他一些人建议的那样,我只会使用一个更独特的ID。
请注意,ID不能以数字开头,因此:
<div class="thing" id="5">
是无效的HTML。请参阅HTML中id属性的有效值是什么?
在情况下,我将使用" thing5"或者" thing.5"之类的ID。
在HTML5中,我们可以这样做:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script> window.addEventListener("DOMContentLoaded", function() { var thing5 = document.evaluate('//*[@data-thing="5"]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE ,null); alert(thing5.singleNodeValue.textContent); }, false); </script> </head> <body> <div data-thing="5">test</div> </body> </html>
根据标准,ID应该是唯一的,尽管大多数浏览器在递给重复的ID时都不会拒绝,但是始终依靠这种情况并不是一个好主意。
通过在ID中添加类型名称来使ID唯一是可行的,但是我们需要询问为什么需要它。当需要查找元素时,给元素一个id是非常有用的,getElementById很快。之所以如此之快,是因为大多数浏览器在加载DOM时会构建一个ID索引。但是,如果我们拥有数不胜数的ID,而实际上根本不需要在诸如getElementById之类的东西中使用ID,那么我们所付出的代价将永远无法收回。
我认为我们可能大多数时候都希望在元素或者其子元素之一触发的事件中获得对象ID。在这种情况下,我将在元素上使用其他属性,而不是ID属性。
我将让class属性去做它打算做的事情,而不是让它承担识别职责。
我不喜欢约翰·米利金的解决方案。对于大型数据集,这将是性能密集型的。
由于id属性的前几个字符是恒定的,因此对他的代码的优化可能是用对substring()的调用来替换正则表达式。
我会选择匹配的"类",然后是一个特定的" id"。
如果我们设置非标准属性,请确保以编程方式设置它们(因为那样一切都会合法),否则将遇到修改dtd!-的麻烦。
但是我会在ID前面加上一个有意义的词,然后在DB-id之前加上ID,然后再使用.getElementById,因为每一个必要的信息都在手边。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
通过DOM跟踪数据对我来说似乎有些不稳定。请记住,这些ID是全局变量,因此,如果其他人的脚本有可能找到进入我们页面的方式,则该漏洞很容易受到攻击。为了获得最佳结果,请将数据加载到匿名函数中的对象中,然后再写入表(或者DIV的大嵌套列表)。