您的位置:首页 > Web前端 > CSS

《JS高程(3)》DOM2和DOM3-样式、视口尺寸问题-第12章笔记(23)

2017-02-17 11:57 507 查看
HTML定义样式3种方法:

<link/>
元素包含外部样式文件;

<style/>
元素定义嵌入式样式;

以及使用style特性定义针对特定元素的样式。

“DOM2级样式”模块就这3种应用样式机制提供了套API。确定浏览器是否支持DOM2级定义的CSS能力:

var supportsDOM2CSS = document.implementation.hasFeature("CSS", "2.0");

var supportsDOMCSS2 = document.implementation.hasFeature("CSS2", "2.0");


访问元素的样式

任何支持style特性的HTML元素在JavaScript中都有一个对应的style属性,这个style对象是CSSStyleDeclaration的实例,包含着通过HTML的style特性指定的所有样式信息,但不包含与外部样式表或嵌入样式表经层叠而来的样式。

CSS属性JavaScript属性
background-imagestyle.backgroundImage
colorstyle.color
displaystyle.display
foot-familystyle.fontFamily
多数情况下,都可以通过简单地转化属性名的格式来实现转换。其中一个不能直接转换的CSS属性就是float。

由于float是JavaScript中的保留字,因此不能用作属性名。

“DOM2级样式”规定样式对象上相应的属性名应是cssFloat;Firefox、Safri、Opera和Chrome都支持这个属性,而IE支持的则是styleFloat.

var myDiv = document.getElementById("myDiv");

//设置背景颜色
myDiv.style.backgroundColor = "red";

//改变大小
myDiv.style.width = "100px";
myDiv.style.height= "100px";

//指定胖子
myDiv.style.border = "1px solid black";


通过style对象同样可以取得在style特性中指定的样式:

<div id = "myDiv" style = "background-color:blue; width:10px; height:25px"></div>


获取style特性中指定的样式信息:

alert(myDiv.style.backgroundColor); //"blue"
alert(myDiv.style.width); //"10px"
alert(myDiv.style.height); //"25px"


DOM样式属性和方法

“DOM2级样式”规范还为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”或者一个空字符串)
通过cssText属性可以访问style特性中的CSS代码,在读取模式下cssText返回浏览器对style特性中CSS代码的内部表示。

在写模式下,赋给cssText的值会重写整个style特性的值。

//cssText改变元素中所有style的变化。
myDiv.style.cssText = "width:25px; height:100px; background-color:green";
alert(myDiv.style.cssText);


length属性的目的,是将其与item()方法配套使用,以便迭代在元素中定义的CSS属性。

使用length和item()时,style对象实际上就相当于一个集合,可以用”[]”来替代item来取得给定位置的CSS属性:

for (var i = 0, len = myDiv.length; i < len; i++){
alert(myDiv.style.item(i))//或者myDiv.style[i]
}


取得CSS属性名为”background-color”,然后,通过getPropertyValue()中使用了取得的属性名进一步取得属性的值:

var prop, value, i, len;
for(i = 0, len = myDiv.length; i < len ; i++){
prop = myDiv.style.item(i);
value = myDiv.style.getPropertyValue(prop);
alert(prop + ":" + value);
}


getPropertyCSSValue()方法返回:cssValueType和cssText.

其中cssText属性的值与getPropertyValue()返回的值相同,而cssValueType属性则是一个数值常量:

0:继承的值
1:基本的值
2:值列表
3:自定义的值
var prop, value, i, len;
for(i=0, len=myDiv.style.length; i < len ; i++){
prop = myDiv.style.item(i);
value = myDiv.style.getPropertyCSSValue(prop);
alert(prop + ":" + value.cssText + "(" + value.cssValueType + ")");
}


removeProperty()方法,用于移除一个属性,意味着将会为该属性应用默认的样式(从其他层叠样式表来):

myDiv.style.removeProperty("border");


计算的样式

“DOM2级样式”增强了document.defaultView,提供了getComputedStyle()方法,接受两个参数:要取得计算样式的元素和一个伪元素字符串(例如:“:after”可为空)。

返回一个CSSStyleDeclaration对象(与style属性的类型相同):

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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>


style设置了backgroundColor和border,没有设置width和height

取得这个元素计算后的样式:

var myDiv = document.getElementById("myDiv");
var computedStyle = document.defaultView.getComputer(myDiv, null);

alert(computedStyle.backgroundColor); // "red"
alert(computedStyle.width); //"100px"
alert(computedStyle.height); // "200px"
alert(computedStyle.border); // 在某些浏览器中是"1px solid black"


操作样式表

CSSStyleSheet类型表示的是样式表,包括通过
<link>
元素包含的样式表和在
<style>
元素中定义的样式表。

这两个元素本身分别由HTMLLinkElement和HTMLStyleElement类型表示的。

var supportsDOM2StyleSheets = document.implenmentation,hasFeature("StyleSheets", "2.0");


CSSStyleSheet继承自StyleSheet,后者可以作为一个基础接口来定义非CSS样式表。从StyleSheet接口继承而来的属性:

disabled:表示样式表是否被禁用的布尔值,可读/写,值为true可以禁用样式表
href:如果样式表是通过< link> 包含的,则是样式表的URL。
media:当前样式表支持的所有媒体类型的集合。
ownerNode:指向拥有当前样式表的节点的指针,样式表可能是在HTML中通过< link >或< style />引入的
title:ownerNode中title属性的值
type:表示样式表类型的字符串。
cssRules:样式表中包含的样式规则的集合
CSS规则

CSSRule对象表示样式表中的每一条规则:

cssText:返回整条规则对应的文本。
parentStyleSheet:当前规则所属的样式表。
selectorText:返回当前规则的选择符文本。
style:一个CSSStyleDeclaration对象,可以通过他设置和取得规则中特定的样式值。
type:表示规则类型的常量值。对于样式规则,值为1。
常用属性:cssText、selectorText和style。

cssText属性与style.cssText属性类似,但并不相同。

cssText包含选择符文本和围绕样式信息的花括号,后者只包含样式信息。

大多数情况下,使用style属性就可以满足所有操作样式规则的需求了。

可以通过他读取和修改规则中的样式信息:

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.backgroundColoe); //"blue"
alert(rule.style.width); // "100px"
alert(rule.style.height); //"200px"


修改样式信息:

var sheet = document.styleSheet[0];
var rules = sheet.cssRules || sheet.rules;  //取得规则列表
var rule = rules[0];
rule.style.backgroundColor = "red"


创建规则

DOM规定,要向现有样式表中添加新规则,需要使用insertRule()方法,参数:规则文本和表示在哪里插入规则的索引。

//DOM方法
//样式表中的第一条规则
sheet.insetRule("body { background-color: silver}", 0);


IE不支持

跨浏览器方法:

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


调用函数的示例代码:

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


这种添加方法比较繁琐。

删除规则

从样式表中删除规则的方法是deletRule()。这个方法接受一个参数:要删除的规则位置。

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


IE支持的类似方法叫removeRule(),使用方法相同:

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);


删除规则可能会影响CSS样式表的层叠效果,慎用。

元素大小

DOM中没有规定如何确定页面中元素的大小,IE率先引入了一些属性,目前,所有主要的浏览器都已经支持这些属性。

偏移量

偏移量:元素在屏幕上占用的所有可见的空间。

元素的可见大小由其高度、宽度决定,包括所有内边距、滚动条和边框大小(注意:不包括外边距)。通过下列4个属性可以取得元素的偏移量:

offsetHeight:元素在垂直方向上占用的空间大小,以像素计。包括元素的高度、(可见的)水平滚动条的高度、上边框高度和下边框高度
offsetWidth:元素在水平方向上占用的空间大小,以像素计。包括元素的宽度、(可见的)垂直滚动条的宽度、左边框宽度和右边框宽度
offsetTop:元素的上外边框至包含元素的上内边框的像素距离
offsetLeft:元素的左外边框至包含元素的左内边框的像素距离


offsetLeft,offsetTop属性与包含元素有关,包含元素的引用保存在offsetParent属性中。

offsetParent属性不一定与parentNode的值相等。

例如:
<td>
元素的offsetParent是作为其祖先元素的
<table>
元素,因为
<table>
是在DOM层次中距
<td>
最近的一个具有大小的元素。

某个元素在页面上的偏移量 ,是将这个元素的offsetLeft和offsetTop与其offsetParent的相同属性相加,如此循环直至根元素,就可以得到一个准确的值。

例子:取得元素的左和上偏移量

function getElementLeft(element){
var actualLeft = element.offsetLeft;
var current = element.offsetParent;

while(current !== null){
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return actuaLeft;
}

function getElementTop(element){
var actualTop += current.offsetTop;
var current = current.offsetParent;

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


这两个函数利用offsetParent属性在DOM层次中逐级向上回溯,将每个层次中的偏移量属性合计到一块。

对于简单的CSS布局的页面,这两个函数可以得到非常精确的结果。

对于使用表格和内嵌框架布局的页面,由于不同浏览器实现这些元素的方式不同,因此值就不精确了。

所有的元素都包含在
<div>
中,而这些
<div>
元素的offsetParent又是
<body>
元素,所以
getElementLeft()
getElementTop()
会返回与offsetLeft和offsetTop相同的值。

客户区大小

元素的客户区大小(client dimension),指的是元素内容及其内边距所占的空间大小。有关客户区大小的属性有两个:clientWidth和clientHeight。

clientWidth属性:元素内容宽度加上左右内边距宽度
clientHeight属性:元素内容高度加上上下内边距宽度


客户区大小就是元素内部的空间大小,滚动条占用的空间不计算在内。

要确定浏览器视口大小,可以使用document.documentElement或document.body的clientWidth和clientHeight。

function getViewport(){
// 检查document.compatMode属性,以确定浏览器是否运行在混杂模式
if (document.compatMode == "BackCompat"){
return(
width: document.body.clientWidth,
height: document.body.clientHeight
);
}else{
return{
//documentElement 属性可返回文档的根节点
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
};
}
}


滚动大小

滚动大小: 包含滚动内容的元素的大小。

scrollHeight:在没有滚动条的情况下,元素内容的总高度
scrollWidth:在没有滚动条的情况下,元素内容的总宽度
scrollLeft:被隐藏在内容区域左侧的像素数。通过设置这个属性可以改变元素的滚动位置。
scrollTop:被隐藏在内容区域上方的像素数。通过设置这个属性可以改变元素的滚动位置。


scrollHeight和scrollWidth主要用于确定元素内容的实际大小。

通常认为
<html>
元素是在Web浏览器的视口中滚动的元素。带有垂直滚动条的页面总高度就是
document.documentElement.scrollHeight


对于不包含滚动条的页面而言,scrollWidth和scrollHeight与clientWidth和clientHeight之间的关系并不十分清晰。在这种情况下,基于
document.documentElement
查看这些属性会在不同浏览器间发现一些不一致性问题:

1.Firefox中这两组属性始终都是相等的,但大小代表的是文档内容区域的实际尺寸,而非是视口的尺寸。

2.Opera、Safari3.1及更高版本、Chrome中的这两组属性是由差别的,其中scrollWidth和scrollHeight等于视口大小,而clientWidth和clientHeight等于文档区域内容的大小。

3.IE(在标准模式)中的这两组属性不相等,其中scrollWidth和scrollHeight等于文档内容区域的大小,而clientWidth和clientHeight等于视口的大小。

在确定文档的总高度时(包括基于视口的最小高度),必须取得scrollWidth/clientWidth和scrollHeight/clientHeight中的最大值,才能保证在跨浏览器的环境下得到精确的结果:

//对于运行在混杂模式下的IE,则需要用document.body代替document.documentElement
var docHeight = Math.max(document.documentElement.scrollHeight, documentElement.clientHeight);

var docWidth = Math.max(document.documentElement.scrollWidth, documentElement.clientWidth);


通过scrollLeft和scrollTop属性既可以确定元素当前滚动的状态,也可以设置元素的滚动位置。

scrollLeft = 0, scrollTop = 0;元素未滚动
scrollLeft = 0, scrollTop > 0;元素垂直滚动
scrollLeft > 0, scrollTop = 0;元素水平滚动
这两个属性都是可以设置的,因此将元素的scrollTop和scrollLeft设置为0,就可以重置元素的滚动位置。

检测元素是否位于顶部,如果不是就将其回滚到顶部:

function scrollToTop(element){
if (element.scrollTop != 0){
element.scrollTop = 0;
}
}


确定元素大小

IE、Firefox3+、Safari4+、Opera9.5及Chrome为每个元素都提供了一个
getBoundingClientRect()
方法。

这个方法返回一个矩形对象,包含4个属性:left、top、right和bottom。这些属性给出了元素在页面中相对于视口的位置。但是,浏览器的视线稍微不同,IE8及更早版本认为文档在左上角坐标是(2, 2),而其他浏览器包括IE9则将传统的(0,0)作为起点坐标。

因此,需要在一开始检查一下位于(0, 0)处的元素的位置,在IE8及更早版本中,会返回(2,2),在其他浏览器中会返回(0, 0):

function getBoundingClientRect(element){
//检测属性是否有定义,没有则定义一个,
if(typeof arguments.callee.offset != "number"){
var scrollTop = document.documentElement.scrollTop;
//创建一个临时元素并定位在(0,0)
var temp = document.createElement("div");
temp.style.cssText = "position:absolute; left:0; top:0;";
document.body.appendChild(temp);
//减去视口的scrollTop,防止调用这个函数式敞口被滚动,offset会被设置为新元素上坐标的负值
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
};
}


对于不支持
getBoundingClientRect()
的浏览器,可以通过其他手段取得相同的信息。一般来说,right和left的差值与
offsetWidth
的值相等,而bottom和top的差值与
offsetHeight
相等。而且,left和top属性大致等于使用本章前面定义的
getElementLeft()
getElementTop()
函数取得的值。跨浏览器的函数:

function getBoundingClientRect(element){

var scrollTop = document.documentElement.scrollTop;
var scrollLeft = document.documentElement.scrollLeft;

if(element.getBoundingClientRect(element)){
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: aotualLeft - scrollLeft,
right: actualLeft + element.offsetWidth - scrollLeft,
top: actualTop - scrollTop,
bottom: actualTop + element.offsetHeight - scrollTop
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  html dom