zoukankan      html  css  js  c++  java
  • Attributes and custom properties(特性与自定义属性)

    在微博上看到有人讨论 attributes 与 properties,甚至 arguments 与 parameters 的区别。正好在看到一篇好的网文,翻译共享。

    文本来自:Attributes and custom properties ——By llya Kantor

    Attributes and custom properties(特性与自定义属性)

    1. Properties
    2. Attributes
    3. Properties 和 Attributes 的同步
      1. id
      2. href
      3. value
      4. class/className
      5. 旧式IE浏览器的乐趣
      6. 作为DOM节点的 Attributes
    4. 总结

    一个 DOM 节点包含 attributes 和 properties。因为彼此间相互关联,人们常常将他们混合在一起,但他们确是两种不同的东西。

    Properties(属性)

    DOM 节点是一个对象,因此可以像 Javascript 中的对象一样存储自定义的 properties 和 methods。

    例子展示了如何给 document.body 添加 properties 和 methods:

    document.body.myData = { 
      name: 'John'
    };
    alert(document.body.myData.name); // John
    
    document.body.sayHi = function() { 
      alert(this.nodeName);
    };
     
    document.body.sayHi();  // BODY

    自定义的 properties 和 methods 仅在 Javascript 中可见,并影响 HTML 。

    同时,自定义 properties 与本地 properties 可用 for..in 循环展示出来:

    document.body.custom = 5;
    
    var list = [];
    for(var key in document.body) {
      list.push(key);
    }
    
    alert(list.join('\n'));

    自定义的 DOM properties:

    • 可为任何类型的值,属性名对大小写敏感。
    • 不影响HTML。

    Attribute(特性)

    DOM 节点提供如下访问 HTML attributes的标准方法:

      elem.hasAttribute(name) - 检查attribute是否存在

      elem.getAttribute(name)  - 获得attribute的值

      elem.setAttribute(name, value) - 设置attribute

      elem.removeAttribute(name) - 删除attribute

     

    IE 8的兼容模式及其以下版本破坏了attributes,这些版本:

    • 只提供了 getAttribute 和 setAttribute 方法
    • 实际修改的是 DOM propertied,而不是 attributes
    • IE 8以下版本中合并了 Attribute 与 property。虽然有时会导致奇怪的结果,但是我们在这讨论的对 attributes 操作方法仍然有效。

    对比 properties,attributes 具有:

    1. 可能只能是字符串(有些会用 toString() 转换)
    2. 名称对大小写不敏感,因为 HTML attributes是不敏感的
    3. 可在 innerHTML 中显示(除非是老的 IE 版本)
    4. 可以用元素属性 .attributes 来列出所有的 attribute,它是个类数组。

    如下例子中展示了一个 HTML 结构,并对其设置 attributes:

    <body>
      <div about="Elephant" class="smiling"></div>
    
      <script>
        var div = document.body.children[0]
        alert( div.getAttribute('ABOUT') ) // (1)
        
        div.setAttribute('Test', 123)      // (2)
        alert( document.body.innerHTML )   // (3)
      </script>
    </body>

    当运行上述代码,注意数字标注的几点:

    1. 虽然 getAttribute('ABOUT‘) 用了大写名称,但并不影响结果。
    2. 可以对 attribute 设置字符串或其他基本类型,这些都将会自动转换成字符串。对象本应当自动转换,但在 IE 中存在问题,因此请坚持使用基本类型。
    3. innerHTML 中包括了新的 ‘test' attribute。

    Properties 与 Attributes 的同步

    每种 DOM 节点都有标准的属性。

    例如,‘A’标签:Interface HTMLAnchorElement。它包含有 'href' 、'accessKey' 以及其他特定的属性。除此之外,它还从 HTMLElement 那继承了 'id' 即其他attribute。

    标准的 DOM properties 与 attributes 是同步的。

    id

    例如,浏览器中 'id‘ attribute与 'id' property是同步的。

    <script>
      document.body.setAttribute('id','la-la-la');
      alert(document.body.id);  // la-la-la
    </script>

    href

    但同步不能保证值也相同。来看看例子中的 ‘href' 属性:

    <a href="#"></a>
    <script>
      var a  = document.body.children[0];
    
      a.href = '/'
      alert( 'attribute:' + a.getAttribute('href') ); // '/'
      alert( 'property:' + a.href );  // IE: '/', others: full URL
    </script>

    这是因为根据 W3C specification,href 必须是一个 ‘well-formed’(良好形式)的链接。

    还有一些属性,它们是同步的,但对于 properties 和 attributes 却不是相同的副本。例如 input.checked :

    <input type="checkbox" checked>
    
    <script>
      var input  = document.body.children[0];
    
      alert( input.checked ); // true
      alert( input.getAttribute('checked') ); // empty string
    </script>

    input.checked 的 property 只能是 true 或者 false,但 attribute可以是任何输入的值。

    value

    同样存在一些 'one-way‘(单向)同步的内置属性。

    例如,input.value 从 attribute 中同步(即 property 从 attribute 中获得同步):

    <body>
      <input type="text" value="markup">
      <script>
        var input = document.body.children[0];
    
        input.setAttribute('value', 'new');
    
        alert( input.value ); // 'new', input.value changed
      </script>
    </body>

    但是 attribute 不能从 property 中获得同步:

    <body>
      <input type="text" value="markup">
      <script>
        var input = document.body.children[0];
    
        input.value = 'new';
    
        alert(input.getAttribute('value'));  // 'markup', not changed!
      </script>
    </body>

    例如当访问者输入了某些字符后,'value' attribute 在 property 更新后维持了原始值。原始值可以用来检验 input 是否变化,或者重置它。

    class/className

    名称的特例:attribute 中的 ‘class’ 对应 property中的 ‘className’

    因为 ‘class' 是 Javascript 的保留字,attribute的 ‘class’ 对应的 property 名称是 ‘className’:

    <body>
      <script>
        document.body.setAttribute('class', 'big red bloom');
    
        alert( document.body.className );  // ^^^
      </script>
    </body>

    注意,上述例子在 IE 9以下的版本不可用,因为怪异模式混合了 properties 和 attributes。

    只要始终使用 className property而不是 class attribute,就可以避免浏览器差异带来的麻烦。

    旧式IE浏览器的乐趣

    首先,IE 9以下的版本同步了所有的 property 和 attribute。

    document.body.setAttribute('try-in-ie', 123)
    
    alert( document.body['try-in-ie'] === 123 )  // true in IE<9

    注意到这里的变量(123)类型是一样的,attribute 并没有将其转换成字符串(实际上它应该转换)。

    其次,在 IE 8以下版本(以及IE 8的IE 7兼容模式)的 properties和 attributes 是相同的。因此产生了一些有趣的结果。

    例如,properties 的名称是大小写敏感的,attributes 却不是。如果浏览器认为它们是相同的,那下面的结果将会是什么样的呢?

    document.body.abba = 1 // assign property (now can read it by getAttribute)
    document.body.ABBA = 5 // assign property with another case
    
    // must get a property named 'ABba' in case-insensitive way.
    alert( document.body.getAttribute('ABba') ) // ??

    浏览器为了避免这种情况,将获得名称的首字母作为默认的大写小形式。IE 还为 getAttribute 提供了一个可选的参数,用来指定大小写形式。详见  MSDN getAttribute

    除了IE 9以下版本的浏览器都可用 ‘class’ attribute 来改变 class 的值。但尽量不要使用它,始终用‘className’ property 代替。

    要想在IE中生存,必须确保正确地使用 attributes。

    或者,始终使用 properties,除非你确实需要用attributes。

    确实需要用 attributes 的情况包括:

    1. 获得自定义的HTML attribute,因为它并不同步到DOM的 property 中。
    2. 获得标准HTML attributes 的原始值,例如<INPUT value = '...'>。

    作为DOM 节点的 attributes

    可以通过 elem.attributes 集合访问元素的 attributes。

    在 attributes 集合中,所有 attribute 都可以表示成一个特殊的DOM节点。它包括名称、值和其他属性。

    例如:

    <span style="color:blue" id="my">text</span>
    
    <script>
      var span = document.body.children[0];
      alert( span.attributes['style'].value );  // "color:blue;"
      alert( span.attributes['id'].value );     // "my"
    </script>

    另外,在IE 8的兼容模式及其以下版本在处理 ‘style’ 属性时会变得疯狂……猜猜为啥?

    Attribute DOM节点不是文档树的一部分,仅仅可从元素来访问它们。

    总结

    Attributes 和 properties 都是DOM模型的核心特征。

    他们的异同表:

    property   attribute
    任意值 字符串
    名称对大小写敏感 不敏感
    innerHTML中不显示 显示
    标准的 DOM properties 和 attributes 是同步的,自定义的不是
    IE 8兼容模式及其以下版本将 attributes 与 properties 混合起来,并且弄得很糟糕

    如果需要在 HTML中自定义 attributes,可以在HTML5中使用  ‘date-* attribute‘ 的形式。详见HTML5标准中的Custom data attributes部分。

    在实际应用中,98%的 DOM 操作都是使用 properties。

    只有两种情形需要使用attributes:

    1. 自定义 HTMLattributes,因为它并不同步到DOM property。
    2. 访问内置的 HTML attributes,这些 attribute 不能从 property 同步过来。例如 INPUT标签的value值。
  • 相关阅读:
    Java 性能优化实战记录(3)--JVM OOM的分析和原因追查
    Map/Reduce的类体系架构
    Map/Reduce个人实战--生成数据测试集
    Ubuntu 16.04下的安装RabbitMQ
    Zookeeper数据存储总结
    Zookeeper原理分析之存储结构ZkDatabase
    Zookeeper原理分析之存储结构TxnLog
    Zookeeper原理分析之存储结构Snapshot
    Kafka迁移与扩容工具用法
    Sublime Text 格式化JSON-pretty json
  • 原文地址:https://www.cnblogs.com/johnnyliu/p/3040156.html
Copyright © 2011-2022 走看看