问题背景

实验中, 在jquery1.7版本, attr("value")  和 val() 接口获取 input 控件的值, 都是一致的, 都是当前控件值。

但是 jquery1.11版本,已经将 这两个接口的返回值分离,  attr("value") 获取的是 控件的初始值(default value),

只有val()属性才能获取到 控件当前值, 例如 用户修改 了输入的值, 必须使用val()获取最新值。

对于 checkbox 和 radio 等控件,  不能使用 val()接口获取,当前值, 需要使用prop("checked")来判断间接判断当前选中控件的值。

经过分析 对于input控件, val接口的实现, 也是调用prop接口来获取 控件的当前值, 即 prop("value").

但是为什么要拆分出 attr 和 property 概念?

查阅MDN相关资料

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/setAttribute

使用 setAttribute() 修改某些属性值时,可能得不到期望结果,尤其是 XUL 中的 value,这是由于 attribute 指定的是默认值。要访问或修改当前值,应该使用 property 属性。例如,使用 elt.value 代替 elt.setAttribute('value', val)

对于属性的改变,或者不改变(保持默认值情况),其当前值并不跟控件的attr属性直接相关。

如果要获取当前属性值, 需要使用属性 dom的 property 来获取 控件。

https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute

Using setAttribute() to modify certain attributes, most notably value in XUL, works inconsistently, as the attribute specifies the default value. To access or modify the current values, you should use the properties. For example, use elt.value instead of elt.setAttribute('value', val).

只解释了 attr 能够设置和获取默认值。

但是property获取的是当前的值。

还是没有解释出根本原因, 为什么要这么设计?

那什么是 attr 什么是 property呢?

什么是attribute?

DOM 的 atrributes

https://developer.mozilla.org/en-US/docs/Web/API/Element/attributes

  The Element.attributes property returns a live collection of all attribute nodes registered to the specified node. It is a NamedNodeMap, not an Array, so it has no Array methods and the Attr nodes' indexes may differ among browsers. To be more specific, attributes is a key/value pair of strings that represents any information regarding that attribute.

什么是attribute?

attribute 对象表达 attribute属性。

https://developer.mozilla.org/en-US/docs/Web/API/Attr

This type represents a DOM element's attribute as an object. In most DOM methods, you will probably directly retrieve the attribute as a string (e.g., Element.getAttribute(), but certain functions (e.g., Element.getAttributeNode()) or means of iterating give Attr types.

Properties

isId
Indicates whether the attribute is an "ID attribute". An "ID attribute" being an attribute which value is expected to be unique across a DOM Document. In HTML DOM, "id" is the only ID attribute, but XML documents could define others. Whether or not an attribute is unique is often determined by a DTD or other schema description.
name
The attribute's name.
ownerElement Deprecated since Gecko 7.0 Obsolete since Gecko 29.0
This property has been removed from Firefox 29. Since you can only get Attr objects from elements, you should already know the owner.
Contrary to above claim, Document.evaluate can return Attr objects from an XPath, in which case you would not easily know the owner.
schemaTypeInfo
?
specified
This property always returns true. Originally, it returned true if the attribute was explicitly specified in the source code or by a script, and false if its value came from the default one defined in the document's DTD.
value
The attribute's value.

以上都是 DOM 结点的 attr 表达形式介绍。

实际上attribute是 html 的属性, 是html的专有名词。

https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Introduction#Attributes

Attributes

The start tag may contain additional information, as in the preceding example. Such information is called an attribute. Attributes usually consist of 2 parts:

  • An attribute name
  • An attribute value

属性表达了 HTML 中 标签的 属性(属性值为字符串), 映射到DOM上表示为 ATTR 对象。

属性 表达的是文档层面的 表达, 为文档加载后的初始状态 和 被修改(例如js 调用 setAttribute接口)的行为,  改变的是文档初始的结构, 并不修改 文档的  当前状态。

即, 通过setAttribute 修改了 value,并不影响 控件当前的value值。 下面介绍property的时候验证。

什么是property?

面向对象的思想, 对象中的所有数据成员都是 property。 见下网址描述:

http://coursesweb.net/actionscript/oop-object-oriented-programming

Object-Oriented programming (OOP) is a specific programming technique to create chunks of programming code (called "objects") that do a specific job, and divide the script into distinct pieces that can be easily managed. These pieces of code can be grouped to form another object.
- For example, the wheels, frame, the pedal, and the handlebars of a bike are separate objects, but if you unite them, they can form a bicycle, which also can be considered an object.
The same is in ActionScript programming, the text, line, shape, movie clip symbol, functions, etc., anything is considered an object.

• Objects are defined using two primary identifiers (or members): properties and methods.

  • Properties - are characteristics that define an object.
    - For example, "color" can be property of a DVD player.
  • Methods - are actions that can be performed by an object.
    For example, Play, and Pause are methods of a DVD player.

对于js中, 使用dom接口获取的一个dom对象后, dom对象有若干暴露于js语言中的 属性, 这些属性, 可能跟 html 标签中的 属性名重复,

例如:

<input id="xx"  name="xx" value="bbb">

document.getElementById("xx").value // bbb

document.getElementById("xx").value = "aaa" // aaa

document.getElementById("xx").getAttribute("value")    //bbb

<!DOCTYPE html><html><head><title>Attributes example</title></head><body>
<input id="xx"  name="xx" value="bbb"><script type="text/javascript">
alert(document.getElementById("xx").value) // bbb

document.getElementById("xx").value = "aaa" // aaa

alert(document.getElementById("xx").value) // aaa

alert(document.getElementById("xx").getAttribute("value"))    //bbb</script></body>
</html>

也有可能不重复, 例如select控件, 没有获取当前值得的value attribute, 但是有value property可以获取当前值:

<select id="xx">

<option value="sss"  selected="selected">sss</option>

<option value="bbb">bbb</option>

</select>

document.getElementById("xx").value // sss

document.getElementById("xx").value = "bbb" // bbb

document.getElementById("xx").getAttribute("value")    //null

<!DOCTYPE html><html><head><title>Attributes example</title></head><body>
<select id="xx"><option value="sss"  selected="selected">sss</option><option value="bbb">bbb</option></select><script type="text/javascript">
alert(document.getElementById("xx").value) // sss

document.getElementById("xx").value = "bbb" alert(document.getElementById("xx").value) // bbb

alert(document.getElementById("xx").getAttribute("value"))    //null</script></body>
</html>

基于上面的代码, 进一步验证, 设置了attbute, 不会改变 property的值。

<!DOCTYPE html>
<html><head><title>Attributes example</title></head>
<body>
<input id="xx" name="xx" value="bbb"><script type="text/javascript">
alert(document.getElementById("xx").value) // bbb
document.getElementById("xx").value = "aaa" // aaa
alert(document.getElementById("xx").value) // aaa
alert(document.getElementById("xx").getAttribute("value")) //bbb
document.getElementById("xx").setAttribute("value", "ccc");
alert(document.getElementById("xx").value) // aaa
alert(document.getElementById("xx").getAttribute("value")) //ccc</script>
</body>
</html>

不仅仅value不一致, a标签的href属性也是不一致的:

http://stackoverflow.com/questions/5874652/prop-vs-attr

var link = document.getElementById('fooAnchor'); alert(link.href); // alerts "http://example.com/foo.html" alert(link.getAttribute("href")); // alerts "foo.html"

JQuery官网的解释

http://api.jquery.com/prop/

Attributes vs. Properties

The difference between attributes and properties can be important in specific situations. Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.

For example, selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked, and defaultSelected should be retrieved and set with the .prop() method. Prior to jQuery 1.6, these properties were retrievable with the .attr() method, but this was not within the scope of attr. These do not have corresponding attributes and are only properties.

在1.6版本之前, attr接口 是考虑获取属性值的 property value, 但是这样导致  非一致的行为

例如 如上面试验结论:

select.value 有, 但是 select.getAttribute("value") 就没有, 如果给 html select标签设置了 value 属性, 则 select.getAttribute("value") 获取的是html标签属性值, select.value 获取的是 控件当前值。

1.6版本之后, 提供了 prop 接口 获取属性值。 这样 getAtrribute 则专职负责获取属性。

W3HELP给出历史变革

http://w3help.org/zh-cn/causes/SD9006

SD9006: IE 混淆了 DOM 对象属性(property)及 HTML 标签属性(attribute),造成了对 setAttribute、getAttribute 的不正确实现

标准参考

根据 DOM (Core) Level 1 规范中的描述,getAttribute 与 setAttribute 为 Element 接口下的方法,其功能分别是通过 "name" 获取和设置一个元素的属性(attribute)值。getAttribute 方法会以字符串的形式返回属性值,若该属性没有设定值或缺省值则返回空字符串。setAttribute 方法则无返回值。
在 DOM Level 2 规范中,则更加明确了 getAttribute 与 setAttribute 方法参数中的 "name" 的类型为 DOMString,setAttribute 方法参数中的 "value" 的类型为 DOMString,getAttribute 的返回值类型也为 DOMString。

DOMString  getAttribute(in DOMString name);
void    setAttribute(in DOMString name, in DOMString value) raises(DOMException);

HTML 文档中的 DOM 对象的属性(property)被定义在 DOM (HTML) 规范中。这个规范中明确定义了 document 对象以及所有标准的 HTML 元素所对应的 DOM 对象拥有的属性及方法。
因为在早期的 DOM Level 0 阶段,某些 HTML 标签的属性会将其值暴露给对应的 DOM 对象的属性,如 HTML 元素的 id 属性与其对应的 DOM 对象的 id 属性会保持一种同步关系,然而这种方式目前已经废弃,这是由于它不能被扩展到所有可能存在的 XML 的属性名称。W3C 建议使用 DOM (Core) 中 Element 接口上定义的通用方法去获取(getting)、设置(setting)及删除(removing)元素的属性。

举例来说,在一个 HTML 文档中存在一个 SPAN 元素,根据 DOM (HTML) 规范,SPAN 元素在页面中生成一个相对应的对象,这个对象派生自 HTMLElement 接口,而 HTMLElement 接口则继承自 Element 接口。HTMLElement 接口中包含 id 属性。我们可以通过 HTMLElement 接口中的 id 属性获得这个元素的标识符,而通过 Element 接口中的 getAttibute 方法传入参数 "id" 同样可以获得标识符。

虽然这两种方式可以获得相同的值,但是却有着天壤之别。

从规范层面上看,getAttribute 方法所属的 DOM (Core) 规范定义了访问和操作文档对象的一套对象和接口,这其中包含了对 HTML 及 XML 的解析及操作;

HTMLElement 接口中 id 属性所属的 DOM (HTML) 规范为 DOM (Core) 的扩展,描述了 HTML 及 XHTML 的对象的细节。

而从 HTML 文档代码的层面上看,一个元素的标记中的 HTML 属性(attribute)与其对应的 DOM 对象的属性(property)也是完全不同的两个概念。

关于 getAttribute 与 setAttribute 的详细信息,请参考 DOM (Core) Level 1 及 Level 2 中的内容。

关于 HTML DOM 对象 的详细信息,请参考 DOM (HTML) Document Object Model HTML,特别是 1.6.1. Property Attributes 中的内容。

只说 dom property不是通用的, 所以使用了更通用的 setatrribute。 根本原因可看不出来,也是语焉不详。

property描述:

https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-642250288

atrribute定义:

https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-637646024

知乎上找到的答案

https://www.zhihu.com/question/38510295/answer/76751073

那么 attributeproperty 有啥区别呢?

  1. attribute 是 HTML 里写好的,property 是 DOM 节点的属性;
  2. 有一些 attribute 会映射到 property (如 value/id 等),有一些 attribute 则不会;
  3. HTML 里写好的 attribute,在映射到 property 时作为 property 的初始值;
  4. 后续的修改最好是直接改 property,改 attribute 不一定生效,关于这一点,每一个浏览器、每一个元素都可能会有自己的行为,data attribute/property 的引入,使得这个问题更复杂了。

DOM SPECIFICATION定义

https://www.w3.org/TR/REC-DOM-Level-1/

dom level 1

The goal of the DOM specification is to define a programmatic interface for XML and HTML. The DOM Level 1 specification is separated into two parts: Core and HTML. The Core DOM Level 1 section provides a low-level set of fundamental interfaces that can represent any structured document, as well as defining extended interfaces for representing an XML document. These extended XML interfaces need not be implemented by a DOM implementation that only provides access to HTML documents; all of the fundamental interfaces in the Core section must be implemented. A compliant DOM implementation that implements the extended XML interfaces is required to also implement the fundamental Core interfaces, but not the HTML interfaces. The HTML Level 1 section provides additional, higher-level interfaces that are used with the fundamental interfaces defined in the Core Level 1 section to provide a more convenient view of an HTML document. A compliant implementation of the HTML DOM implements all of the fundamental Core interfaces as well as the HTML interfaces.

从上面可以看到,

The DOM Level 1 specification is separated into two parts: Core and HTML.

Core -- 负责文档结构。

HTML -- 负责 HTML 文档的便利使用。

DOM core attr 接口:

https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-745549614

IDL Definition
interface Element : Node {readonly attribute  DOMString            tagName;DOMString                 getAttribute(in DOMString name);void                      setAttribute(in DOMString name, in DOMString value)raises(DOMException);void                      removeAttribute(in DOMString name)raises(DOMException);Attr                      getAttributeNode(in DOMString name);Attr                      setAttributeNode(in Attr newAttr)raises(DOMException);Attr                      removeAttributeNode(in Attr oldAttr)raises(DOMException);NodeList                  getElementsByTagName(in DOMString name);void                      normalize();
};

这样我们豁然开朗, attr 也只对文档的结构负责。

影响:

http://www.tuicool.com/articles/6NVvaeE

property与attribute都是dom的核心功能,鉴于有的属性上会出现单项同步的情况似乎attribute貌似更保险一点,以下是二者的关系表:

作用:

可以使用attr接口构造dom节点, 这个层面上, 仅仅是文档结构(此时遵守 DOM CORE), 其负责文档的初始形式;

DOM HTML的接口也被添加到DOM节点上(不管DOM有没有加入文档流中), property属性都可以调用,改变动态改变的状态。

下面给出例子证明, attr是文档初始值, property是动态改变的值。

首先构造了一个input text控件, 控件value attr最终被设置为  ccc

将此控件插入文档, 插入文档的位置为  form 表单, 其中包括一个 reset 按钮。 

页面显示后, 点击reset按钮, input输入框的值变为 ccc。

<!DOCTYPE html><html><head><title>Attributes example</title></head><body><form><input type="reset" name="reset" value="reset"></form><script type="text/javascript">
var input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("name", "q");
input.setAttribute("value", "bbb");
//input.setAttribute("class",bordercss);

input.value = "aaa"document.forms[0].appendChild(input)input.setAttribute("value", "ccc");</script></body>
</html>

显示:

点击reset后

JQuery1.11版本对prop和attr接口的含义分离导致问题分析相关推荐

  1. jquery1.6中的.prop()和.attr()异同

    1.从1.5.2升级到1.6.1 通过介绍新方法.prop()以及.attr()方法的改变,jQuery1.6.1引起了一场关于attributes和properties之间有何区别和联系的激烈讨论. ...

  2. Jquery1.6版本后attr的变化

    原文链接:http://www.cnblogs.com/-run/archive/2011/11/16/2251569.html Jquery1.6版本后attr的变化 Jquery1.6版本后 at ...

  3. JVM(Java SE 11版本)加载类和接口

    本文介绍了Java虚拟机(Java SE 11版本)加载类和接口. 加载类和接口 加载是指查找具有特定名称的类或接口类型的二进制形式的过程.典型的做法是,查找事先由Java编译器从源代码计算而来二进制 ...

  4. jquery中prop()和attr()的使用

    jquery1.6+出现的prop()方法. • 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法.  • 对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法. • ...

  5. jquery-1.11.1.js

       每次想要使用这个js时,总是要到官网上下载,太麻烦,现在把它收录了 jquery-1.11.1.js /*!* jQuery JavaScript Library v1.11.1* http:/ ...

  6. jquery-1.11.3.min.js —— jquery库

    转载地址:https://www.cnblogs.com/SongHuiJuan/p/8058217.html jquery-1.11.3.min.js -- jquery库 /*! jQuery v ...

  7. java11 是长期支持_这里有你不得不了解的Java 11版本特性说明

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  8. jquery-1.11.3.js与jquery-1.11.3.min.js区别

    2019独角兽企业重金招聘Python工程师标准>>> 唯一的区别就是在: Download the compressed, production jQuery 1.11.3,Pro ...

  9. 燕千云 YQCloud 数智化业务服务管理平台发布1.11版本

    2022年3月25日,燕千云 YQCloud 数智化业务服务管理平台发布1.11版本.新增客户服务管理模块.优化IT服务管理功能.增强燕千云与其他平台的集成能力.支持更多的业务服务场景.全面提升企业数 ...

最新文章

  1. 【BZOJ3926】[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机
  2. selector + drawable 多状态图形
  3. 我们究竟还要学习哪些Android知识?完整版开放下载
  4. 个人数据在暗网的交易价格是多少?
  5. 孕妇能长期在计算机屏幕前工作吗,怀孕了在电脑前工作怎么办
  6. Socket编程实践(11) --epoll原理与封装
  7. C# .NET 使用 NPOI 生成 .xlsx 格式 Excel
  8. 教你如何使用FusionInsight SqoopShell
  9. discuz 服务器维护,论坛服务器经常宕机 - Discuz!-安装使用 - Discuz! 官方站 - Powered by Discuz!...
  10. Red Hat Enterprice Linux 5测试 Qt 4.7 Qt Creator(二)
  11. T61|NV显卡门|根据售后维修部数据显示爆发期来临|预防显卡门|解决显卡门
  12. 二元函数对xy同时求导_2020.5.6 | 考研数学—多元函数微分学重要考点攻克
  13. 好看的微信忧心文案小程序源码 文案+头像+背景图
  14. 【图灵机器人】图灵机器人API V2版使用采坑指南
  15. 哥伦比亚大学公众人物脸部数据集
  16. 浅析信号与系统1(指数信号与正弦信号)
  17. 【硬盘】2021-西部数据叠瓦盘(SMR)、垂直盘(CMR/PMR)型号、容量大全
  18. Linux命令date命令
  19. Android开发经验谈-很少有人会告诉你的Android开发基本常识
  20. 如何下载广西壮族自治区卫星地图高清版大图

热门文章

  1. L1-019. 谁先倒-PAT团体程序设计天梯赛GPLT
  2. android cmd里查看systemapp剩余空间不足,解决emui系统内部存储空间不足的办法
  3. mysql创建和修改索引_MySQL索引创建 删除 增加 修改命令
  4. oracle 判断非空字段
  5. ArcGIS9.3 SDE安装
  6. 面试系列-Java面试总则
  7. Apache Flume 简介
  8. Idea配置sbt(window环境)
  9. davlik虚拟机内存管理之一——内存分配
  10. Com原理及應用——Com對象和接口