【javascript】CSS-DOM

一、三位一体的网页

  1. 结构层:由HTML或XHTML之类的标记语言负责创建
  2. 表示层:由CSS负责完成
  3. 行为层:负责内容如何响应事件,由javascript和DOM负责。

二、style属性
例如,有以下例子

<p id="example" style="color:grey;font-family:'Arial',sans-serif;">An example of paragraph
</p>

style属性包含着元素的样式,查询这个属性将返回一个对象。
1.获取样式
为查出某个元素在浏览器中的颜色,需要使用style对象中的color属性:

element.style.color

绝大部分样式表的属性的返回值与它们的设置值都采用同样的单位,但存在例外。如color属性值是#999999,在有些浏览器里,其在DOM中的color属性是以RGB格式的颜色值返回。

注意:需要饮用一个中间带有减号的CSS属性,DOM要求使用驼峰是命令,如font-family可以转换为fontFamily

通过style属性获取样式有很大的局限性,style属性只能返回内嵌样式,即只有把CSS style属性插入到标记里,才可以使用DOM style属性去查询这些信息。

2.设置样式
style对象的各个属性都是可读写的,可以用赋值语句来更新样式

element.style.property = value

style对象的属性值永远是一个字符串,因此其数值值必须放在引号里,否则javascript会解释成一个变量,引发错误。

三、何时该用DOM脚本设置样式
在绝大多数场合,还是应该是会用CSS去声明样式,在一些使用CSS不方便的场合,可以利用DOM对文档的样式做一些增强。
1.根据元素在节点树中的位置来设置样式

通过CSS声明样式的方式主要有3种:

  1. 为标签元素统一地声明样式
p {
	font-size:1em;
}
  1. 为特定class属性的所有元素统一声明样式
.fineprint {
	font-size:.8em;
}
  1. 为独一无二的id属性单独声明样式
#intro {
	font-size:1.2em;
}

现今,CSS还无法根据元素之间的相对位置关系找出某个特定的元素,但这对DOM来说很容易实现。我们可以利用DOM找出文档中所有的h1元素,然后找出紧跟在每个h1元素后面的元素,并为它们添加样式。
如:
首先用getElementsByTagName方法把所有的h1标签找出来,然后遍历这个节点里的所有元素,文档里的下一个节点可以用silbing属性查找出来。注意:这里需要的是下一个元素节点,因此需要编写getNextElement函数。

function styleHeaderSibling(){
	if (!document.getElementsByTagName) return false;
	var headers = document.getElementsByTagName("h1");
	var elem;
	for(var i=0;i<headers.length;i++){
        headers[i].nextSibling
        elem = getNextElement(headers[i].nextSibling);
        elem.style.fontWeight = "bold";
        elem.style.fontSize = "1.2em";
	}
}

function getNextElement(node){
	if (node.nodeType == 1) return node;
	if (node.nextSibling) return getNextElement(node.nextSibling);
	return false;
}

addLoadEvent(styleHeaderSibling);

对应的htm文档:

<!DOCTYPE html>
<html lang="en">
	<head>
        <meta charset="utf-8"/>
        <title>Man bites dog</title>
	</head>
	<body>
        <h1>Hold the front page</h1>
        <p>This first paragraph leads you in.</p>
        <p>The most important information is delivered first.</p>
        <h1>Extra! Rxtra!</h1>
        <p>Further developments are unfolding.</p>
        <p>You can read all about it here.</p>
        <script src="scripts/addLoadEvent.js"></script>
        <script src="scripts/styleHeaderSibling.js"></script>
	</body>
</html>

2.根据某种条件反复设置某种样式
表格:

让表格里的行更可读的常用技巧是交替改变它们的背景色,从而使相邻的两行泾渭分明。如果浏览器支持CSS 3,只需要如下两行样式:

tr:nth-child(odd){
	background-color:#ffc;
}
tr:nth-child(even){
	background-color:#fff;
}

如果:nth-child()不可用,只好采用另外的技术。有一种方案是为每个奇数行设置一个class即可,但是不够方便,特别是以后要在这个表格的中间插入或删除行,需要手动更新大量的class属性。

可以利用javascript使用for或while循环来遍历。

function stripeTables(){
	if (!document.getElementsByTagName) return false;
	var tables = document.getElementsByTagName("table");
	var odd,rows;
	for (var i=0;i<tables.length;i++){
        odd = false;
        rows = tables[i].getElementsByTagName("tr");
        for (var j=0;j<rows.length;j++){
            if (odd == true){
                rows[j].style.backgroundColor = "#ffc";
                odd = false;
            }else{
                odd = true;
            }
        }
	}
}

addLoadEvent(stripeTables);

对应的html代码:

<DOCTYPE html>
<html lang="en">
	<head>
        <meta charset="utf-8" />
        <title>Cities</title>
        <link rel="stylesheet" media="screen" href="styles/format.css">
	</head>
	<body>
        <table>
            <caption>Itinerary</caption>
            <thead>
                <tr>
                    <th>When</th>
                    <th>Where</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>June 9th</td>
                    <td>Portland,<abbr title="Oregon">OR</abbr></td>
                </tr>
                <tr>
                    <td>June 10th</td>
                    <td>Seattle,<abbr title="Washington">WA</abbr></td>
                </tr>
                <tr>
                    <td>June 12th</td>
                    <td>Sacramento,<abbr title="Califonia">CA</abbr></td>
                </tr>
            </tbody>
        </table>
        <script src="scripts/addLoadEvent.js"></script>
        <script src="scripts/stripeTables.js"></script>
	</body>
</html>

3.响应事件
CSS提供的:hover等伪class属性允许我们根据HTML元素的状态来改变样式。DOM也可以通过onmouseover等事件对HTML元素的状态变化作出相应。
很难判断何时应该使用:hover属性,何时应该使用onmouseover事件。最简单的方法就是选择最容易实现的办法。

比如,如果想让链接在鼠标指针悬停在其上时改变颜色,就选用CSS

a:hover{
	color:#c60;
}

伪类:hover已经得到了绝大多数浏览器的支持——至少被用来改变链接样式时是如此。但如果想利用该伪类在鼠标悬停在其他元素上时改变样式,支持这种用法的浏览器就没那么多了。

如果想让某行在鼠标指针悬停其上时改变文本变为粗体,可以使用CSS(以前面的html为例)

tr:hover{
	font-weight:bold;
}

然而,在实际中,只有部分浏览器看到效果。
在这种场合,使用DOM改变HTML元素的样式更切合实际。

编写函数highlightRows函数,将鼠标指针选悬停在某个表格行的上方时,把该行文本加黑加粗。

function highlightRows(){
	if (!document.getElementsByTagName) return false;
	var rows = document.getElementsByTagName("tr");
	for (var i=0;i<rows.length;i++){
        rows[i].onmouseover = function(){
            this.style.fontWeight = "bold";
        }
        rows[i].onmouseout = function(){
            this.style.fontWeight = "normal";
        }
	}
}

addLoadEvent(highlightRows);

4.className属性
className是一个可读/可写的属性,凡是元素节点都有这个属性。

for(var i=0;i<headers.length;i++){
    headers[i].nextSibling
    elem = getNextElement(headers[i].nextSibling);
    elem.style.fontWeight = "bold";
    elem.style.fontSize = "1.2em";
}

观察以上代码,如果想要将紧跟在一级标题后的元素的CSS改为1.4em,需要去改变这个函数。如果引用一个外部CSS样式表,并且其中有一条针对.intro类的样式声明:

.intro{
	font-weight:bold;
	font-size:1.2em;
}

现在只需要在styleHeaderSibling函数里将紧跟在一级标题后的元素的class属性设置为intro即可达到同样的目的。可以使用setAttribute方法,element.setAttribute(“class”,“intro”),也使用直接更新className属性。

function styleHeaderSibling(){
	if (!document.getElementsByTagName) return false;
	var headers = document.getElementsByTagName("h1");
	var elem;
	for(var i=0;i<headers.length;i++){
		elem = getNextElement(headers[i].nextSibling);
		elem.className = "intro";
	}
}

此时,只需要在CSS中修改.intro类的样式声明即可。

注意:通过className属性设置某个class属性时将替换该元素原来的class属性。

若需要达到追加效果,可编写函数addClass。

function addClass(element,value){
	if (!element.className){
    element.className = value;
    }else{
        newClassName = element.className;
        newClassName += "";
        newClassName += value;
        element.className = newClassName;
	}
}

对函数进行抽象
我们发现styleHeaderSiblings函数,它仅适用于h1元素,而且className的属性值也是硬编码在函数代码里的,我们通过将这些具体的值转换为这个函数的参数,就可以让它成为一个更通用的函数,将新函数命名为styleElementSiblings,并给它们增加两个参数——tag和theclass。

function styleHeaderSibling(tag,theclass){
	if (!document.getElementsByTagName) return false;
	var elems = document.getElementsByTagName("tag");
	var elem;
	for(var i=0;i<elems.length;i++){
		headers[i].nextSibling
		elem = getNextElement(elems[i].nextSibling);
		addClass(elem,theclass)
		// elem.style.fontWeight = "bold";
		// elem.style.fontSize = "1.4em";
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值