DOM有什么不好的地方?


42

我一直在听到人们(尤其是Crockford)说DOM是一个糟糕的API,但并没有真正证明这一说法的合理性。除了跨浏览器不一致之外,为什么认为DOM如此糟糕还有哪些原因?


31
Apart from cross-browser inconsistencies这还不够吗?
扬尼斯,2012年

3
有人问过同样的问题(包括对Crockford的提及),但由于在SO方面没有建设性,所以将其关闭:DOM有什么问题?
蚊蚋

3
大多数说DOM很糟糕的人要么无知,要么说旧版浏览器很糟糕
Raynos'5

事件传播模型是错误的:它不允许父节点覆盖子事件处理程序以添加自定义行为。在OOP中,它称为虚函数,多态性和委托(通过组合继承)。首先从上到下捕获事件,然后冒泡。在榆树中,他们实施了非常适当的可组合模型,其中事件先冒泡然后“被捕获”(从父母到孩子的传播)。它允许取消事件(“关闭窗口?”),并覆盖/装饰子组件的行为。
Brian Haak

Answers:


33

Crockford进行了广泛的演讲,题目是“一个不方便的API:Dom的理论”,他或多或少地解释了他对DOM的看法。它很长(1h 18m),但是正如大多数Crockford的演讲中那样,它非常有趣并且富有教育意义。

跨浏览器不一致似乎是他的主要关注点,我同意这是DOM最令人讨厌的事情。他确定:

  • 专有陷阱(浏览器和服务器陷阱),
  • 打破规则,
  • 企业战,
  • 极限时间压力

作为各种不一致背后的关键问题,在网络的原始视野中从来没有想到要添加演示文稿,会话或交互性。不一致的一些示例包括:

  • document.all,仅Microsoft的一项功能,
  • nameid过去可以互换的事实。
  • 检索节点上的不同功能:
    • document.getElementById(id)
    • document.getElementsByName(name)
    • *node*.getElementsByTagName(tagName)

并继续提供更多示例,主要针对遍历DOM,内存泄漏以及事件滴漏和冒泡。有一个名为“ The Cracks of DOM”的摘要幻灯片,其中总结:

  • DOM错误列表包括浏览器中的所有错误。
  • DOM错误列表包括所有受支持的浏览器中的所有错误。
  • 没有DOM完全实现标准。
  • 在任何标准中都没有描述很多DOM。

简而言之,这是一个凌乱的API。看起来似乎很挑剔,但是您必须记住,在为Web开发时,很少会选择客户将使用的浏览器。必须在每个主要浏览器的至少两个版本中测试所有内容很快就会过时。一个API应该是一致的,而DOM是浏览器之战的受害者,但是它变得越来越好。它仍然不像W3C(我想我们所有人)想要的那样与平台无关,但是与五到十年前相比,浏览器供应商似乎更渴望合作。


18
跨浏览器不一致与DOM无关。这就是我们所谓的“旧版浏览器”。不要将DOM归咎于旧版浏览器的存在。这就像说“ Linux很烂,因为我知道旧版发行版和M,它们很烂”。
雷诺斯(Raynos)


@Raynos是的,不是。浏览器供应商长期以来一直是Web标准发展的主要力量,这使所有事情搞砸了,与linux的类比并没有太大意义。我要强调的是DOM本身并不是错误的,它是错误的实现和标准演变的不连贯方式。就拿document.all例如,它在标准,但作为故意违反
扬尼斯,2012年

1
我不会为人们将旧版浏览器和DOM混淆而感到恼火。我发表了评论。对于旧版浏览器,只需放弃对它们的支持就很简单了。有球去做。您可以控制开发寿命,也可以由IE8控制。我控制我的。
雷诺斯(Raynos)

3
好答案;您还没有提到的另一个烦人之处是DOM API非常冗长-只需比较典型的jQuery代码,例如在特定节点上插入具有一些属性的元素即可,而普通DOM版本则执行相同的操作。
tdammers 2012年

15

DOM有什么问题?除了受Java启发的语法(Crockford提到过)之外,什么也没有。

“错误”部分适用于浏览器供应商。“错误”适用于开发人员;什么是“错误”适用于无知。

那么,从哪里开始呢?

在兔子洞下…

浏览器供应商

首先,浏览器供应商经过数十年的竞争,成为“最佳”,“最快”,“最简单”等。在最初的十年(199x-2000)中,微软占据了主导地位。Internet Explorer引入了一些创新的想法,例如:

  • 将浏览器的HTML解析引擎公开为innerHTMLouterHTML
  • 易操控的文本与innerTextouterText;
  • 事件模型(*tachEvent),它是DOM 2级事件(*EventListener)的蓝图。

每个人都为当今的Web开发堆栈做出了很大的贡献(无论好坏)。Opera甚至在版本7(2003)中实现了这三个功能。

但是,Netscape有其自己的DOM事件模型(*EventListener)。在2000年,它成为DOM 2级事件规范。Safari 1(2003)实现了此模型;Opera 7(2003)也实现了该模型。随着Netscape的废墟变成Mozilla,Firefox 1(2004)继承了该模型。

在第二个十年的第一部分(2000年至2004年),微软占据了上风。Internet Explorer 6(2001)是当时最好的浏览器。它的竞争对手之一Opera 6(2001)尚未实现DOM Level 1 Core(createElement等)。在规范甚至成为推荐标准(1998)之前,Microsoft在Internet Explorer 4(1997)中实现了它。

但是,第二个十年(2004-2010年)的第二部分对微软来说将是灾难性的。苹果在2003年发布了Safari 1.0;在2004年,Mozilla完成了Firefox 1.0。微软似乎在浏览器山顶上睡着了。Internet Explorer 7直到2006年才发布:距Internet Explorer 6的发布日期还有五年的时间。与Internet Explorer版本4到6不同,版本7几乎没有创新。DOM变化很小。将近两年半后,Internet Explorer 8被发布。微软已经从沉睡中醒了过来,注意到其他浏览器供应商围绕许多Web标准形成了联合。不幸的是,自微软上一次真正的创新以来已经过去了太多的时间。浏览器供应商之间已经掀起了一场运动。新的DOM功能将以规范形式添加到W3C。微软的想法是过去留下的。微软的事件模型(*tachEvent)避开了DOM Level 2事件模型。Internet Explorer直到版本9(2011)才实现之前的模型,该版本成为DOM Level 3事件模型。

微软(DOM)的愚蠢可以归纳为以下几点:

  • 存在作为Windows的核心功能,以及由此产生的OS级安全要求;

  • 依靠ActiveX获得客户端代码;

  • 在第6版(2001)之后就逐渐减少的创新。


(网络)开发人员

其次,开发人员应承担一定的责任。随着网络的不断发展,越来越多的人开始涉足网络开发。这导致了人才和职业道德的淡化。但是,问题主要在于态度。“快速完成”优先于“正确完成”。结果,无数的网页与各种浏览器不兼容。这种不兼容的主要原因之一是一种称为“用户代理嗅探”的做法。尽管这种做法今天仍在使用,但事实证明它既错误又有害。Opera甚至将版本10(2009)及更高版本中的用户代理版本“冻结”为“ 9.80”。目的是防止错误的脚本被破坏。一种更好的做法叫做“


无知

第三,我最希望责备的是无知。浏览器供应商的协作程度不足以创建统一的规范,这一事实无知;微软不回避其他浏览器用户的事实;无知的事实,开发商是不是太懒惰,太短视打扰研究浏览器(尤其是那些没有成为时尚。)有在API和实现许多差异。通过简化的防御方法(依赖DOM 0)以及大量的研究和测试,可以避免大多数情况。无知导致了Internet Explorer 6对地球的危害(请回想一下它在前面提到的浏览器宝座上的位置)。


反射

可悲的是,DOM只是一个被误解的API。许多人希望通过FUD扔石头,但很少有人希望学习它的复杂性。这种无知的结果是引入了DOM“选择器”。DOM的核心是用于处理文档树的API。给定已解析文档的形式,应将树遍历用于复杂问题。通过引入DOM Selectors API,开发人员现在可以利用浏览器的CSS遍历引擎。这很方便,但是它隐藏了文档树的真实形式。使用“选择器”,元素节点检索是基本的。但是,DOM还指定了其他11种节点类型。什么是文本节点?评论节点?文件节点?这些也是与DOM交互时经常需要的节点。


结论

简而言之,请花一些时间阅读各种DOM规范。在尽可能多的浏览器中测试代码。如果认为Internet Explorer行为异常,请咨询MSDN。大多数情况下,行为已记录在案。

(历史轶事可能而且可能是不准确的;任何不准确之处都欢迎提出。)

—马特


Opera甚至甚至“冻结”了 -我讨厌这种方法,因为它是很短视的(一些开发人员无法编写代码,所以让我们搞砸API来帮助他们)。当客户坚持要修复的浏览器中存在特定错误时,通常需要获取浏览器类型和版本。修复特定的浏览器比实现某些“错误检测”要容易得多(例如,“功能检测”的相反过程)。
Pavel Horal

3

DOM是一个糟糕的API

那是错误的。DOM不是一个糟糕的API。

  • 首先,请记住DOM与语言无关。所有主要语言均已实现该API。这是因为您只是不在浏览器中使用它,而是在任何需要处理XML的地方使用它。

  • 其次,请注意,DOM不是定义类而是接口。这具有非常重要的含义:语言可以按照适合其构造和哲学的方式来实现它。这使所有语言都不必与其他语言保持一致。

  • 第三,DOM是解析XML的两种主要方法之一(其他方法是SAX),根据您的上下文,DOM可能非常有效。

您指的是浏览器DOM。而且,我同意DOM在浏览器中“感觉”不好。部分原因是浏览器不兼容。但是,我不同意它们是DOM在浏览器中声誉不好的唯一原因。

  • 首先,如果您考虑一下,DOM是相对容易克服这些不兼容性的领域之一。相比之下,例如,事件要复杂得多,而且烦恼要规范化。

  • 其次,DOM特征的特征检测比其他领域更简单。

  • 第三,DOM 3更好-今天所有的浏览器都支持它。

当然,不兼容会令人烦恼,但是当您陷入困境时,DOM就会减少很多麻烦。

我也不同意私有陷阱,公司战等原因。

  • 我认为这是JavaScript的一种哲学(轻量级语言)与DOM的实现受到Java启发之间的脱节-造成了许多沮丧。

  • 其次,DOM已针对XML设计,并且已针对HTML进行了修改。因此,在浏览器中,我们恰好有两个DOM(HTML DOM和XML DOM),它们是不兼容的。

  • 第三,浏览器中的DOM遍历不好。我们没有用于HTML DOM的XPath,因此在CSS选择器引擎之前,进行遍历确实很繁琐。

最后,我认为今天,在现代浏览器(以及较旧的浏览器逐渐消失)中,没有理由将DOM称为“坏”。它肯定会在浏览器中变得更好-API和实现。


正常化的事件也一样微不足道:\
雷诺斯(Raynos)2012年

考虑一下-如果您必须支持currentTarget事件对象的属性-这会很琐碎吗?
treecoder

实现事件冒泡就像一条100行代码:\
Raynos 2012年

currentTarget不仅仅是事件冒泡-实现自己的事件冒泡真的明智吗?
treecoder

1
并与dataManager坐在外面,你说的代码是微不足道的?:)
treecoder 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.