在现代JavaScript应用程序中使用DOM Level 0的最佳实践

在现代JavaScript应用程序中是否有一套商定的“最佳实践”用于DOM Level 0集合 ? ( document.formsdocument.images等)

在使用jQuery的应用程序中,我注意到,例如,使用$(...).html()更改下拉列表的内容以切换底层节点,而不是使用element.options[] 。 这是因为最好避免使用DOM 0集合,还是因为jQuery使更改底层DOM结构变得更容易?

编辑:我想部分问题包括旧function是否可靠的跨浏览器。 我记得很久以前,IE会自动将

标签添加到你的桌面,而firefox则不会。 这使得走在dom树上痛苦的跨浏览器。 同样, element.options[] 在更改集合中的选项时遇到问题 。 这些家伙是否可靠跨浏览器?

首先,好问题。

DOM Level 0-1function是我最喜欢的工具箱。 支持是巨大的。 我将在下面突出显示DOM Level 0的每个子集的优缺点:

DOM级别0事件

由于这些是作为ElementNode的属性添加的,因此您只能拥有一个处理程序。 对于某些情况(例如:事件委托),这是繁重的。 但是,我觉得DOM足够多(特别是当你的项目变大时)为DOM级别0处理程序提供足够的空间。 没有库/框架来平滑旧版浏览器,DOM Level 2监听器很难实现。 即使作为Flash开发人员(在任何地方都使用了侦听器),DOM 0事件对我来说也容易得多。 其中一个亮点是this值是为你设置的(没有IE浏览器和其他模型咳嗽)。 例如,考虑这个标记:

Cick Me!

现在,需要做的就是选择和附加DOM Level 0处理程序。

 var foo = document.getElementById("foo"); function bar() { console.log(this); //
} foo.onclick = bar;

这是一种非常简单的选择元素的方法, 也是Event.currentTarget的替代方法 ;

这里有关于DOM Level 0事件与DOM Level 2事件的讨论:[ link ]


DOM Level 0 HTMLCollections

没有, HTMLCollections是我最喜欢的DOMfunction。 因为为您选择了节点,所以不需要运行查询。 在我看来,它们是当今最容易被忽视的DOMfunction。 名称遍历如: collection["name"]非常方便,在遍历表单时肯定有帮助。 例如,考虑一下这个标记:

 
Dummy Form

有许多DOM Level 0方法可以解决这个问题。

  1. var foo = document.forms.foo; //

    演示: http : //jsbin.com/udozoz/0edit#preview

  2. var foo = document.forms[0]; //

    演示: http : //jsbin.com/udozoz/2/edit#preview

  3. var foo = document.getElementById("foo"); //

    演示: http : //jsbin.com/udozoz/3/edit#preview

当然,方法3是更优选的。 它是DOM级别1,而不是DOM级别0.但是,名称遍历自然适合HTMLFormElement.elements HTMLCollection 。 由于您应该在表单元素上使用name属性,因此您可以轻松访问它们而不使用id属性。

例如: var baz = foo.elements.baz;

使用共享相同名称的单选按钮(一次只能选择一个)时,可以使用HTMLFormElement.elements HTMLCollection选择所有单选按钮。 这非常强大。 考虑这个标记:

 
Radio Buttons

你可以使用这个简单的代码,让每个单选按钮的name属性值为“selectable”:

  1.  var foo = document.forms.foo; var selectables = foo.elements.selectable; console.log(selectables); //[input#select_1 a, input#select_2 b, input#select_3 c] 

    演示: http : //jsbin.com/upiyom/edit#preview

  2.  var foo = document.forms.foo; var selectables = foo.selectable; console.log(selectables); //[input#select_1 a, input#select_2 b, input#select_3 c] 

    演示: http : //jsbin.com/upiyom/2/edit#preview

选项2使您可以完全绕过elements HTMLCollection 。 虽然肯定不如选项1那么清晰,但它仍然在今天使用。

自从引入DOM Level 0以来, HTMLCollections已经变得更加人口稠密,而且更加多样化。例如,看看可用于表的HTMLCollections 。 这令人震惊。 有HTMLTableElement.rows , HTMLTableElement.tBodies , HTMLTableSectionElement(thead,tbody,tfoot).rows和HTMLTableRowElement.cells 。 这些集合非常强大,并且使用表格进行DOM遍历变得更加简单(允许您使用它们)。


DOM级别0属性

虽然ElementNodes上的属性在DOM级别0中并不像现在这样多,但仍有几个gem需要注意:

HTMLInputElement.defaultChecked

defaultChecked使您可以完全绕过搜索HTMLInputElement的checked属性,因为它根据该属性的值存储布尔值。 这意味着您不必通过与get / set / removeAttribute相关的IE构建的草率解决方案进行克服。 稍后,还将添加defaultValue属性以填充类似的需求。

document.lastModified [非标准]

lastModified将存储文档上次更改的时间。 这是一个很酷的小function,使用有限。

HTMLDocument.title

title将为你抓住文档的标题。 它的使用充其量只是一个小利基。


关于你的tbody问题,如果你不提倡正确的DOM结构,今天的浏览器会添加一个HTMLTableSectionElement (tbody)。 您应该了解正确的表标记,以便将来不会出现问题:)。

示例标记:

错误:

 
Hello, World!

对:

 
Hello, World!

演示: http : //jsbin.com/exomub/edit#preview


摘要

需要被驱动回家的要点是DOM级别0的大部分都是在DOM级别1和2中标准化的。这意味着浏览器支持是广泛的(因为它确实很旧)。 除了旧浏览器版本中的一些边缘情况之外,不应该过多担心使用它。 在一天结束时,这是你的选择。

我想补充一点,我过去只是非常简短地使用HTML / JavaScript进行开发。 我这是一个爱好,所以我不知道有关浏览器/项目出错的“恐怖故事”。

我希望这清除了一些事情。

-Matt

ElementNodenodeType == 1节点

HTMLCollection – 浏览器收集的类似实时arrays的NodeList

这是一个非常有趣的问题。 这是我的两分钱。

首先,它可能不言而喻,但这取决于您正在处理代码。 专业程序员的目标是遵循公司范围内(或者,对于大型公司,团队范围内)最佳实践,如果这些准则不鼓励或禁止DOM级别0,那么您不应该使用它。 如果允许或根本不提及,那么决定将解决为个人选择,例如您自己的代码。

现在,如果您愿意,没有明显的技术缺陷阻止您使用0级。 例如,如果迭代element.options比使用element.getElementsByTagName("option")$("option", element)慢,我会感到惊讶。 第一种语法也可以说比替代语言更具可读性。

浏览器支持也不是问题。 0级比污垢更老,并且在太阳下每个脚本感知浏览器都支持超过十年。

但是,以上是关于选择 ,而不是效率 ,这是你的问题的后半部分所关注的。 实际上,您可以以或多或少相同的效率迭代element.options$("option", element)$(element).children("option") ,但是如果你必须做大量工作(例如,消灭现有的元素并添加新的元素,然后使用element.innerHTML$(element).html()肯定会更快。

这是因为innerHTML Level 0属性和html() jQuery方法(内部使用innerHTML )都将所有标记解析和DOM操作委托给浏览器,浏览器通常用较低级别的语言编写,并针对这些任务进行了大量优化。 在Javascript循环中逐个删除元素总是比较慢,在这种情况下,使用DOM Level 0或jQuery的所有铃声和口哨绝对没有区别。

我首先要说的是,我不知道任何“官方”声明,如“DOM Level 0被认为有害”。 这只是我自己的看法。

我认为这取决于具体情况。

我遇到的问题是,使用像documents.formsdocuments.images这样的集合来定位特定元素是有问题的,特别是对于动态生成/修改的documents.images 。 每次我看到有人写document.forms[0] ,我都会畏缩。

当前甚至不那么流行的浏览器通过诸如getElementsByTagName函数来提供能力来模拟相同的行为,但是以更通用和可重用的方式。 当然,当你将jQuery添加到混合中时,根本就没有理由使用这些集合。

我遇到的例外情况是,当你在非jQuery环境中工作并且你正在访问诸如selectElement.optionstbodyElement.rows类的东西时。 在这些情况下,当您执行添加或删除项目等基本操作时,它确实更简单。

在使用jQuery的应用程序中,我注意到有一种趋势,比如,使用$(…)。html()更改下拉列表的内容以切换底层节点,而不是使用element.options [] 。 这是因为最好避免使用dom0集合,还是因为jQuery使更改底层DOM结构变得更容易?

这可以很容易地解释。 95%的jQuery开发人员不了解DOM API存在或可以使用的事实。

事实上,jQuery被滥用于DOM可以更容易地做的事情,这简直是由于没有学习DOM的人造成的。

就个人而言,我会说使用DOM 0,但话说回来,我个人会说使​​用DOM垫片而不使用jQuery。 这都是一个选择问题。

做任何最可维护的事情

无论好坏,我使用纯DOM级别0function主要用于调试。 检查document.forms [0]。输入元素有时会更快。

当我正在检查一些使用一些深奥(或根本不为我)的框架的页面时,我也使用这些function。 我没有时间深入研究这些抽象,只是直接检查馆藏。

我确实相信你会更好地了解所有这些DOM零库,但如果你知道所有这些现代纯DOM不知道哪个级别它是exaclty级API,它会更好。 例如,ClassList集合很好。 我的意思是,如果你使用的是框架,你应该总是知道,为什么你确实需要它。