草庐IT

javascript - 元素属性与其对应属性之间关系背后的设计原因

coder 2023-08-01 原文

我对某些 DOM 元素的 property 与其对应的 attributes 之间的关系如何运作背后的原因感到困惑。

下面是 jquery in action 2015 Bear Bibeault 一书中的图表,显示了 DOM 元素的 propertyattribute 之间的关系。

为了进一步说明概念,作者有如下代码以及对代码的解释。

我的问题是,为什么有的propertyattribute同步,有的不同步,有的attributes没有对应属性

我找到了 great post解释了propertyattribute之间的关系,但没有涉及为什么要这样设计。我希望了解设计背后的原因。

一个相关的问题,如果我想在 DOM 元素上获取或设置一个值,我应该获取/设置 property 还是 attribute

我们如何在需要时找到特定 property 与其对应的 attribute 之间的关系?是否有专门详细说明这种关系的文档?

最佳答案

DOM 是在很大程度上“自然”生长的东西。你必须考虑,HTML(意思是:属性)是第一位的,最初没有任何脚本。最终,Netscape 引入了 JavaScript,你今天会认为这是一个极其有限的 API。这个 API 适用于操作表单,而不是真正的任意 HTML 元素。然后 Netscape 和 Internet Explorer 推出了当时称为 DHTML(动态 HTML)的不同变体。 Netscape 的变体依赖于一个特殊的 <layer>标签,今天没有人记得它。 Internet Explorer 变体允许对 HTML 元素进行更通用的访问,尤其是具有属性到特性的 1:1 映射。

虽然 Internet Explorer 赢得了这场 war ,但它的 DHTML 变体是在人们将 HTML 属性名称视为固定集合时设计的。具有任意属性,它有太多问题。例如:

  • class属性最初无法映射到 JavaScript,因为 class是保留关键字。虽然 JavaScript 标准的后续更改允许使用保留关键字作为属性名称,但 Internet Explorer 必须映射 class属性为 className属性(property)。设置className元素上的属性或 el["class"] JavaScript 对象上的属性导致了可笑的不一致。
  • HTML 属性不区分大小写,而 JavaScript 属性区分大小写。所以 Internet Explorer 有各种各样的技巧来识别意图。当元素为 <FOO SOMEATTIRIBUTE> 时发生了什么你试图访问 el.someAttributeel.SOMEATTRIBUTE来自 JavaScript?我不记得了,但它并不漂亮。
  • JavaScript 对象也总是有方法。属性 toString例如不能映射到属性,因为它会掩盖 toString()方法。

除了 Internet Explorer 之外,没有其他浏览器实现过这种属性到属性的 1:1 映射,甚至 Internet Explorer 在向后兼容方面可行时也放弃了它(这花了很长时间)。相反,属性和属性现在被视为单独的 namespace 。浏览器会为您提供一些属性作为属性访问和操作的快捷方式,但它们实际上只是为了您的方便。还有一些向后兼容的情况使水变得困惑:value属性(property)和value属性实际上并不相互映射,前者反射(reflect)元素的当前状态,而后者反射(reflect)其初始状态。

编辑:仅供引用,您引用以下声明:

If attribute exists as a built-in property but it's a Boolean, the value isn't synchronized.

这是错误的,该行为与 bool 值与字符串无关。如上所述,value属性与 checked 同样缺少同步属性(property)。另一方面, bool 值 hidden属性将与相应的属性正确同步。据我所知,您会发现 Netscape 引入的原始表单操作 API 的属性和特性之间缺少同步 - 这只是向后兼容性。

因此,也许您不应该相信那些用 DOM 问题撰写有关 jQuery 书籍的人。毕竟,这些明确地选择停止直接接触 DOM,并选择了一种完全不同的表示方式,它有自己的一套怪癖。

关于javascript - 元素属性与其对应属性之间关系背后的设计原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49247529/

有关javascript - 元素属性与其对应属性之间关系背后的设计原因的更多相关文章

  1. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  2. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  5. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  6. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  7. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  8. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  9. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下

  10. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

随机推荐