1. 程式人生 > >《Javascript 高階程式設計(第三版)》筆記0x14 DOM2和DOM3:樣式

《Javascript 高階程式設計(第三版)》筆記0x14 DOM2和DOM3:樣式

目錄

樣式

     訪問元素的樣式

       DOM 樣式屬性和方法

        計算的樣式

    操作樣式表

        CSS 規則

        建立規則

        刪除規則

    元素大小

        偏移量(offset dimension)

         客戶區大小(client dimension)

         滾動大小(scroll dimension)

         確定元素大小


樣式

        在 HTML 中定義樣式的方式有 3 種:通過<link/>元素包含外部樣式表文件、使用<style/>元素定義嵌入式樣式,以及使用 style 特性定義針對特定元素的樣式。

//確定瀏覽器是否支援 DOM2 級定義的 CSS 能力
var supportsDOM2CSS = document.implementation.hasFeature("CSS", "2.0");
var supportsDOM2CSS2 = document.implementation.hasFeature("CSS2", "2.0");

     訪問元素的樣式

        在 style 特性中指定的任何 CSS 屬性都將表現為這個style 物件的相應屬性。對於使用短劃線(分隔不同的詞彙,例如 background-image)的 CSS 屬性名,必須將其轉換成駝峰大小寫形式,才能通過 JavaScript 來訪問。

 

var myDiv = document.getElementById("myDiv");
//設定背景顏色
myDiv.style.backgroundColor = "red";
//改變大小
myDiv.style.width = "100px";
myDiv.style.height = "200px";
//指定邊框
myDiv.style.border = "1px solid black";

       DOM 樣式屬性和方法

        “DOM2 級樣式”規範還為 style 物件定義了一些屬性和方法。這些屬性和方法在提供元素的 style特性值的同時,也可以修改樣式。

    cssText:通過它能夠訪問到 style 特性中的 CSS 程式碼。
    length:應用給元素的 CSS 屬性的數量。
    parentRule:表示 CSS 資訊的 CSSRule 物件。
    getPropertyCSSValue(propertyName):返回包含給定屬性值的 CSSValue 物件。
    getPropertyPriority(propertyName):如給定的屬性使用了!important 設定,則返回"important";否則,返回空字串。
    getPropertyValue(propertyName):返回給定屬性的字串值。
    item(index):返回給定位置的 CSS 屬性的名稱。
    removeProperty(propertyName):從樣式中刪除給定屬性。
    setProperty(propertyName,value,priority):將給定屬性設定為相應的值,並加上優先權標誌("important"或者一個空字串)。

myDiv.style.cssText = "width: 25px; height: 100px; background-color: green";
alert(myDiv.style.cssText);

//設計 length 屬性的目的,就是將其與 item()方法配套使用,以便迭代在元素中定義的 CSS 屬性。
for (var i=0, len=myDiv.style.length; i < len; i++){
	alert(myDiv.style[i]); //或者 myDiv.style.item(i)
}

//可以在 getPropertyValue()中使用取得的屬性名進一步取得屬性的值
var prop, value, i, len;
for (i=0, len=myDiv.style.length; i < len; i++){
	prop = myDiv.style[i]; //或者 myDiv.style.item(i)
	value = myDiv.style.getPropertyValue(prop);
	alert(prop + " : " + value);
}

var prop, value, i, len;
for (i=0, len=myDiv.style.length; i < len; i++){
	prop = myDiv.style[i]; //或者 myDiv.style.item(i)
	value = myDiv.style.getPropertyCSSValue(prop);
	alert(prop + " : " + value.cssText + " (" + value.cssValueType + ")");
}

myDiv.style.removeProperty("border");

        計算的樣式

        “DOM2 級樣式”增強了 document.defaultView,提供了getComputedStyle()方法。這個方法接受兩個引數:要取得計算樣式的元素和一個偽元素字串(例如":after")。如果不需要偽元素資訊,第二個引數可以是 null。getComputedStyle()方法返回一個 CSSStyleDeclaration 物件(與 style 屬性的型別相同),其中包含當前元素的所有計算的樣式。

<!DOCTYPE html>
<html>
	<head>
		<title>Computed Styles Example</title>
		<style type="text/css">
			#myDiv {
			background-color: blue;
			width: 100px;
			height: 200px;
			}
		</style>
	</head>
	<body>
		<div id="myDiv" style="background-color: red; border: 1px solid black"></div>
	</body>
</html>
var myDiv = document.getElementById("myDiv");
var computedStyle = document.defaultView.getComputedStyle(myDiv, null);
alert(computedStyle.backgroundColor); // "red"
alert(computedStyle.width); // "100px"
alert(computedStyle.height); // "200px"
alert(computedStyle.border); // 在某些瀏覽器中是"1px solid black"

    操作樣式表

       CSSStyleSheet 型別表示的是樣式表,包括通過<link>元素包含的樣式表和在<style>元素中定義的樣式表。

var sheet = null;
for (var i=0, len=document.styleSheets.length; i < len; i++){
	sheet = document.styleSheets[i];
	alert(sheet.href);
}

//在不同瀏覽器中都能取得樣式表物件
function getStyleSheet(element){
	return element.sheet || element.styleSheet;
}
//取得第一個<link/>元素引入的樣式表
var link = document.getElementsByTagName("link")[0];
var sheet = getStylesheet(link);

        CSS 規則

    CSSRule 物件表示樣式表中的每一條規則。實際上, CSSRule 是一個供其他多種型別繼承的基類a型,其中最常見的就是 CSSStyleRule 型別,表示樣式資訊(其他規則還有@import、 @font-face、@page 和@charset,但這些規則很少有必要通過指令碼來訪問)。

    CSSStyleRule 物件包含下列屬性。
    cssText:返回整條規則對應的文字。由於瀏覽器對樣式表的內部處理方式不同,返回的文字可能會與樣式表中實際的文字不一樣; Safari 始終都會將文字轉換成全部小寫。 IE 不支援這個屬性。
    parentRule:如果當前規則是匯入的規則,這個屬性引用的就是匯入規則;否則,這個值為null。 IE 不支援這個屬性。
    parentStyleSheet:當前規則所屬的樣式表。 IE 不支援這個屬性。
    selectorText:返回當前規則的選擇符文字。由於瀏覽器對樣式表的內部處理方式不同,返回的文字可能會與樣式表中實際的文字不一樣(例如, Safari 3 之前的版本始終會將文字轉換成全部小寫)。在 Firefox、 Safari、 Chrome 和 IE 中這個屬性是隻讀的。 Opera 允許修改 selectorText。
    style:一個 CSSStyleDeclaration 物件,可以通過它設定和取得規則中特定的樣式值。
    type:表示規則型別的常量值。對於樣式規則,這個值是 1。 IE 不支援這個屬性。

/*
div.box {
	background-color: blue;
	width: 100px;
	height: 200px;
}
*/

//獲取
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules; //取得規則列表
var rule = rules[0]; //取得第一條規則
alert(rule.selectorText); //"div.box"
alert(rule.style.cssText); //完整的 CSS 程式碼
alert(rule.style.backgroundColor); //"blue"
alert(rule.style.width); //"100px"
alert(rule.style.height); //"200px"

//設定
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules; //取得規則列表
var rule = rules[0]; //取得第一條規則
rule.style.backgroundColor = "red"

        建立規則

sheet.insertRule("body { background-color: silver }", 0); //DOM 方法

sheet.addRule("body", "background-color: silver", 0); //僅對 IE 有效

function insertRule(sheet, selectorText, cssText, position){
	if (sheet.insertRule){
		sheet.insertRule(selectorText + "{" + cssText + "}", position);
	} else if (sheet.addRule){
		sheet.addRule(selectorText, cssText, position);
	}
}

insertRule(document.styleSheets[0], "body", "background-color: silver", 0);

        刪除規則

sheet.deleteRule(0); //DOM 方法

sheet.removeRule(0); //僅對 IE 有效

function deleteRule(sheet, index){
	if (sheet.deleteRule){
		sheet.deleteRule(index);
	} else if (sheet.removeRule){
		sheet.removeRule(index);
	}
}
deleteRule(document.styleSheets[0], 0);

    元素大小

        偏移量(offset dimension)

    元素的可見大小由其高度、寬度決定,包括所有內邊距、滾動條和邊框大小(注意,不包括外邊距)。通過下列 4 個屬性可以取得元素的偏移量。
    offsetHeight:元素在垂直方向上佔用的空間大小,以畫素計。包括元素的高度、(可見的)水平滾動條的高度、上邊框高度和下邊框高度。
    offsetWidth:元素在水平方向上佔用的空間大小,以畫素計。包括元素的寬度、(可見的)垂直滾動條的寬度、左邊框寬度和右邊框寬度。
    offsetLeft:元素的左外邊框至包含元素的左內邊框之間的畫素距離。
    offsetTop:元素的上外邊框至包含元素的上內邊框之間的畫素距離

/*要想知道某個元素在頁面上的偏移量,將這個元素的 offsetLeft 和 offsetTop 與其 offsetParent
的相同屬性相加,如此迴圈直至根元素,就可以得到一個基本準確的值。*/
function getElementLeft(element){
	var actualLeft = element.offsetLeft;
	var current = element.offsetParent;
	while (current !== null){
		actualLeft += current.offsetLeft;
		current = current.offsetParent;
	}
	return actualLeft;
}

function getElementTop(element){
	var actualTop = element.offsetTop;
	var current = element.offsetParent;
	while (current !== null){
		actualTop += current. offsetTop;
		current = current.offsetParent;
	}
	return actualTop;
}

         客戶區大小(client dimension)

function getViewport(){
	if (document.compatMode == "BackCompat"){
		return {
			width: document.body.clientWidth,
			height: document.body.clientHeight
		};
	} else {
		return {
			width: document.documentElement.clientWidth,
			height: document.documentElement.clientHeight
		};
	}
}

         滾動大小(scroll dimension)

/*
在確定文件的總高度時(包括基於視口的最小高度時),必須取得 scrollWidth/clientWidth 和
scrollHeight/clientHeight 中的最大值,才能保證在跨瀏覽器的環境下得到精確的結果。
*/
var docHeight = Math.max(document.documentElement.scrollHeight,
	document.documentElement.clientHeight);
var docWidth = Math.max(document.documentElement.scrollWidth,
	document.documentElement.clientWidth);

//檢測元素是否位於頂部
function scrollToTop(element){
	if (element.scrollTop != 0){
		element.scrollTop = 0;
	}
}

         確定元素大小

function getBoundingClientRect(element){
	var scrollTop = document.documentElement.scrollTop;
	var scrollLeft = document.documentElement.scrollLeft;
	if (element.getBoundingClientRect){
		if (typeof arguments.callee.offset != "number"){
			var temp = document.createElement("div");
			temp.style.cssText = "position:absolute;left:0;top:0;";
			document.body.appendChild(temp);
			arguments.callee.offset = -temp.getBoundingClientRect().top - scrollTop;
			document.body.removeChild(temp);
			temp = null;
		}
		var rect = element.getBoundingClientRect();
		var offset = arguments.callee.offset;
		return {
			left: rect.left + offset,
			right: rect.right + offset,
			top: rect.top + offset,
			bottom: rect.bottom + offset
		};
	} else {
		var actualLeft = getElementLeft(element);
		var actualTop = getElementTop(element);
		return {
			left: actualLeft - scrollLeft,
			right: actualLeft + element.offsetWidth - scrollLeft,
			top: actualTop - scrollTop,
			bottom: actualTop + element.offsetHeight - scrollTop
		}
	}
}