JavaScript特性(attribute)、屬性(property)和樣式(style)


一、DOM特性和DOM屬性

attribute(特性),是我們賦予某個事物的特質或對象,attribute是HTML標簽上的特性,它的值只能夠是字符串

property(屬性),是早已存在的不需要外界賦予的特質,property是DOM中的屬性,是JavaScript里的對象

在訪問元素特性值時有兩種方式:

1. 傳統DOM方法getAttribute和setAttribute。

2. 使用DOM對象上與之對應的屬性。

例如通過兩種方式獲取id的值:

e.getAttribute('id');
e.id;

1)跨瀏覽器命名

特性和屬性命名之間的差異會更多。

在大多數瀏覽器中可以用class獲取到class特性,但IE卻要使用className。

2)命名限制

特性表示為傳遞給DOM方法的字符串,其命名規范是非常自由的。

而屬性名稱,由於可以作為標識符使用點表示法進行訪問,所以其命名規范更受限制。

3)HTML和XML之間的差異

在處理一個XML DOM的時候,不會在元素上自動創建屬性值來表示特性值。

因此,我們需要使用傳統的DOM特性方法獲取特性的值。

elem.ownerDocument只讀屬性會返回當前節點的頂層的 document 對象。

function isXML(elem) {
  return (elem.ownerDocument || elem.documentElement).nodeName.toLowerCase() !== 'html';
}

4)自定義特性的行為

要想訪問自定義特性值,需要使用DOM方法getAttribute()與setAttribute()。

在HTML5中,對所有的自定義特性使用“data-”前綴。

5)性能注意事項

總的來說,屬性的訪問速度比相應DOM特性方法的訪問速度要快,特別是在IE瀏覽器中。

下面做個測試,分別用兩種方式讀取和設置500W次。可以在不同瀏覽器中點開這個地址來查看測試結構。

下面的截圖是在Chrome中的結果:

 

二、跨瀏覽器的Attribute問題

1)DOM中的id/name膨脹

5大瀏覽器都會將表單input元素的id和name特性作為<form>元素的屬性值進行引用。

產生的這些屬性,會主動覆蓋form元素上已經存在的同名屬性。

此外,IE瀏覽器不僅會替換屬性值,甚至還會替換該屬性值上的特性值。

<form id="testForm" action="/">                       
      <input type="text" id="id"/>
      <input type="text" name="action"/>
</form>
var form = document.getElementById('testForm');
assert(form.id === 'testForm', "the id property is untouched");
assert(form.action === '/', "the action property is untouched");
assert(form.getAttribute('id') === 'testForm',  "the id attribute is untouched");
assert(form.getAttribute('action') === '/', "the action attribute is untouched");

在所有的現代瀏覽器中,由於這些input定義的id和name的值,表單的id和action屬性都會被input元素的引用所替代。

解決方法是獲取描述元素特性本身的原始DOM節點,該節點沒有被瀏覽器修改:

var action = element.getAttributeNode('action').nodeValue;

2)URL規范化

在訪問一個引用了URL屬性時(例如src、href或action),該URL值會自動將原始值轉換成完整規范的URL。

<a href="listing-11.5.html" id="testSubject">Self</a>
var link = document.getElementById('testSubject');
var linkHref = link.getAttributeNode('href').nodeValue; //#1

assert(linkHref === 'listing-11.5.html',  'link node value is ok');
assert(link.href === 'listing-11.5.html',  'link property value is ok');
assert(link.getAttribute('href') == linkHref, 'link attribute not modified');

3)style特性

HTML DOM元素有一個style屬性,通過該屬性我們能獲取元素的樣式信息,例如element.style.color。

<span style="color:red"></span>

如果要獲取“color:red”字符串,那么style屬性沒用,得用getAttribute('style')方法獲取。

但IE中得用element.style.cssText獲取。

4)節點名稱

在HTML文檔中,nodeName屬性返回的名稱將是大寫(例如HTML、BODY)。

在XML或XHTML文檔中,nodeName返回的名稱是用戶指定的名稱,可以大寫、小寫或混合。

 

三、令人頭疼的樣式特性

1)樣式在何處

<style>
      div { font-size: 1.8em; border: 0 solid gold; }
</style>
<div style="color:#000;" title="Ninja power!">
      忍者
</div>
復制代碼
var div = document.getElementsByTagName("div")[0];

assert(div.style.color == 'rgb(0, 0, 0)' ||  div.style.color == '#000','color was recorded');

assert(div.style.fontSize == '1.8em', 'fontSize was recorded');
assert(div.style.borderWidth == '0', 'borderWidth was recorded');
div.style.borderWidth = "4px";                    //#6
assert(div.style.borderWidth == '4px', 'borderWidth was replaced');
復制代碼

1. 大多數顏色都會轉換成RGB顏色符號,有一些會轉換為顏色的名稱。

2. font-size和border都被記錄在了style標簽內,樣式是繼承獲取的,但div.style屬性中沒有獲取到。

3. 一個元素的style屬性中的任何一個樣式的優先級都要高於樣式表所繼承的樣式(即便使用了“!important”注解規則)。

2)樣式屬性命名

CSS特性將多余一個單詞的用連字符分隔,例如font-size、font-weight等。

在JS中可以用帶有連字符的樣式名稱,但不能使用點運算符來訪問樣式了。

var size = element.style['font-size'];//允許
var size = element.style.font-size;//不允許
var size = element.style.fontSize;//允許

在JS中多個單詞的CSS樣式名稱用駝峰的方式命名,例如fontSize、fontWeight。

具體的CSS樣式表對應屬性可以參考《CSS Properties Reference

3)設置多個樣式屬性

不能通過直接給style屬性設置字符串(如:elt.style = "color: blue;")來設置style,因為style應被當成是只讀的。

設置多個屬性可以用cssText或setAttribute,其中cssText會將重復屬性覆蓋屌。

elt.style.cssText = "color: blue"; // 設置多個樣式屬性 當帶前綴的時候-webkit-transform:rotate(0deg),會過濾掉-webkit,只能用下面的方式
elt.setAttribute("style", "color: blue"); // 設置多個樣式屬性 

4)float樣式屬性

float是JS中的保留關鍵字,瀏覽器需要提供另外一個替代名稱。

大部分瀏覽器使用cssFloat,但IE使用styleFloat。

5)像素值的轉換過程

為style屬性設置數字時,必須要指定單位,以便在所有的瀏覽器上都能使用。

element.style.height = '10px';//安全
element.style.height = 10;//不安全

6)測量元素的高度和寬度

offsetHeight和offsetWidth可以獲取元素的高度和寬度,不過這兩個屬性值包括了padding值,更多元素尺寸屬性可以參考《JavaScript中尺寸、坐標

但如果元素隱藏(例如display:none),獲取到的數值都是0。對於隱藏元素可以用如下的方法:

可以查看在線demo實例

“Pole”是顯示的圖片,就是那個忍者。

而“Shuriken”是隱藏的圖片,一開始是獲取不到寬度的,在使用了上面的技巧后就能獲取到了。

7)通過opacity看透明度

所有現代瀏覽器,包括IE9支持opacity屬性,但IE9之前的版本需要使用專用的alpha過濾法。

opacity: .5;
filter: alpha(opacity=50)

支持opacity的瀏覽器,總會將值規范為小於1.0且以0開頭的值。

例如“opacity:.5”,那么支持的將返回“0.5”,不支持的將返回“.5”。

通過特性仿真,可以判斷瀏覽器是否支持opacity。

//特性仿真檢測
var div = document.createElement("div");                 //#1
div. setAttribute('style','opacity:.5');
var OPACITY_SUPPORTED = div.style.opacity === "0.5";

assert(OPACITY_SUPPORTED,   "Opacity is supported.");

8)顏色屬性

通過不同的計算樣式方法訪問這些顏色值的時候,各種瀏覽器的返回值幾乎都不一致。

下面是一個在線demo,在不同瀏覽器中展示的顏色值:

IE8

Firefox Chrome
IE8不支持RGBA和HSL格式

Firefox不僅保留了顏色名稱,

而且標准顏色是RGB和RGBA格式

Webkit瀏覽器(Chrome、Safari)

標准顏色是RGB和RGBA格式

 

四、獲取計算樣式

1)window.getComputedStyle()與element.currentStyle

一個元素的計算樣式(computed style)都是應用在該元素上的所有樣式組合。

這些樣式包括樣式表、元素的style特性,以及腳本對style屬性的各種操作。

現代瀏覽器(包括IE9)的實現方法為:window.getComputedStyle(),返回接口提供了一個getPropertyValue()的方法。

IE9之前的版本,通過附加到所有元素上的currentStyle屬性,表現和style屬性一樣。

復制代碼
/**
* property可以傳入駝峰或分隔符方式
*/
function fetchComputedStyle(element, property) { //#3
  //現代瀏覽器 包括IE9
  if (window.getComputedStyle) {
    var computedStyles = window.getComputedStyle(element); //#4
    if (computedStyles) { //#5
      property = property.replace(/([A-Z])/g, '-$1').toLowerCase();
      return computedStyles.getPropertyValue(property);//getPropertyValue中需要傳入分隔符字符串,例如font-size
    }
  } else if (element.currentStyle) { //IE9以下
    property = property.replace(
      /-([a-z])/ig,
      function(all, letter) {
        return letter.toUpperCase();
      });
    return element.currentStyle[property];
  }
}
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



猜您在找 JavaScript特性(attribute)、屬性(property)和樣式(style) 區分元素特性attribute和對象屬性property WPF樣式中TargetType 屬性 (Property) 和 x:Key 屬性 (Attribute) js便簽筆記(2)——DOM元素的特性(Attribute)和屬性(Property) python之中特性(attribute)與屬性(property)有什么區別? JavaScript的attribute和property辨析 屬性attribute和property的區別 用javascript插入