JS DOM编程艺术学习笔记(三)

第九章 CSS-DOM

如何利用DOM技术获取(读)和设置(写)CSS信息
1、三位一体的网页

 我们在浏览器里看到的网页是由三层信息构成的共同体:结构层,表示层,行为层
 结构层:由HTML或XHTML之类的标记语言创建——标签
 表示层:CSS描述页面内容如何呈现
 行为层:负责内容如何响应——JavaScript和DOM
 网页设计应做到结构、行为、样式相分离。

2.style属性

文档的每个节点元素都有一个属性style,包含着元素的样式,查询这个属性将返回一个对象object而不是简单地字符串,样式都存放在style对象的属性里。
获取样式:element.style.color,注意带“-”的属性,如font-family,js会把他解释为减号,所以DOM要求使用驼峰命名法:fontFamily。
注意!DOM style属性不能用来检索在外部CSS文件里声明的样式,和放在<head>里面的<style>样式,只能返回行间内嵌样式(标签中的style)。
     但这并没有实际用途,因为我们提倡结构与样式相分离,但是还有另外一种情况能让DOM style对象正确反映出我们设置的样式:
设置样式:element.style.color="black";

3.用DOM脚本设置样式

通过CSS声明样式的具体做法有三种:
(1)标签元素统一声明样式    p {  font-size:1em; }
(2)有特定class属性的所有元素统一声明样式  .fineprint{  }
(3)独一无二id属性元素单独声明样式    #intro {    }

但是CSS还无法根据元素之间的相对位置关系找出某个特定元素,并添加样式,但是DOM可以。

A.根据元素节点在树里的位置设置样式
在CSS3中,可以使用h1~*选择器为所有的h1元素的下一个同辈元素声明样式,但是目前很多浏览器还不支持CSS3的这种位置选择器。
但是可以用DOM找出文档中所有的h1元素,然后再找出紧跟在每个h1元素后面的那个元素,并把样式添加给它

首先,用getElementsByTagName找出所有h1:
var headers=document.getElementsByTagName("h1");
for( var i=0;i<headers.length;i++)
{
然后,寻找下一元素节点函数,遍历这个节点集合里的所有元素,文档中的下一节点用nextSibling找出,但是下一节点不一定是元素节点,这里用到递归调用
function getNextElement(node) {         //声明getNextElement函数,参数为node节点。
  if(node.nodeType == 1) {              //如果node节点为元素节点,则返回node
  return node;
  }                                     //如果node节点类型值与1相等为假,则继续执行下面语句。 
  if (node.nextSibling) {               //如果node节点的下一个兄弟节点存在,则递归,参数变为node节点的下一个兄弟节点。
    return getNextElement(node.nextSibling);    //从一个函数的内部调用这个函数本身叫作递归调用
  }                                      //如果node节点的下一个兄弟节点不存在即条件为假,则继续执行下面语句。
  return null; 
}
最后,将h1的下一个节点作为参数传给getNextElement函数,把封装到函数styleHeaderSibling中
function styleHeaderSibling() {
       if(!document.getElementsByTagName) return false;
       var elem;
       var headers=document.getElementsByTagName("h1");
       for( var i=0;i<headers.length;i++)
          {
             elem=getNextElement(headers[i].nextSibling);
             elem.style.fontWeight= "blod" ;
             elem.style.fontSize= "1.2em";
           }  
  }
  function getNextElement(node) ……省略 addLoadEvent(styleHeaderSibling);
B.根据某种条件反复设置某种样式
设置表格隔行同色
function stripeTables() {
    if (!document.getElementsByTagName) return false;
    var tables = document.getElementsByTagName("table");
    for (var i=0; i<tables.length; i++) {
        var odd = false;
        var rows = tables[i].getElementsByTagName("tr");
        for (var j=0; j<rows.length; j++) {
            if (odd == true) {
                rows[j].style.backgroundClor="#ffc";
                odd = false;
            } else {
                odd = true;
            }
        }
    }
}
 C.响应事件
 只想让链接在鼠标指针悬停在其上时改变颜色,就应该用CSS——:hover伪类在鼠标移到元素上时向此元素添加特殊的样式。
      a:hover{ color:#c60; }  
注释:为了产生预期的效果,在 CSS 定义中,a:hover 必须位于 a:link 和 a:visited 之后!!
注释:为了产生预期的效果,在 CSS 定义中,a:active 必须位于 a:hover 之后!!

 为了避免浏览器不支持,DOM也可以实现。
    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);
心得:如果想改变某个元素的呈现效果,使用CSS
     如果想改变某个元素的行为,使用DOM
     如果想根据某个元素的行为改变呈现效果,最简单的解决方案是什么?哪种会得到更多浏览器的支持?

4.className属性

 className是个可读可写的属性element.className
 可以避免在js文件中设置具体样式,只需要借助CSS的类名通过className修改对象样式。
 只有一个不足,只能替换样式,不能追加样式。
 如何追加呢?可以使用字符串拼接操作,把新的class设置追加到className属性上去(请注意新加类名前的空格)
elem.className +=" intro"; 
 需要给元素新追加class时,可以按照一下步骤操作:
 (1)检查className属性是否为null
 (2)如果是,把新的class设置直接赋值给className属性
 (3)如果不是,把一个空格和新的class设置追加到className属性上
function addClass(element,value){
            if(!element.className){
                element.className=value;
            }else{
                newClassName=element.className;
                newClassName+=" ";
                newClassName+=value;
                element.className=newClassName;
            }
        }

第十章 动画效果
1.时间

setTimeout("function",interval)能够让某个函数在经过一段预定时间后开始执行,"function"通常是一个字符串,内容是要执
行的那个函数的名字;第二个参数是一个数值;通常将它赋值给一个变量。通过setTimeout函数暂停一段时间后执行代码,可以实现一些特殊的效果
variable=setTimeout("function",interval);
如果想取消某个正在排队等待执行的函数,用clearTimeout;
clearTimeout(variable);

2.抽象moveElement

function moveElement(elementID,final_x,final_y,interval) {
      if (!document.getElementById) return false;
      if (!document.getElementById(elementID)) return false;
      var elem = document.getElementById(elementID);
      if (elem.movement) {
        clearTimeout(elem.movement);
      }
      var xpos = parseInt(elem.style.left);
      var ypos = parseInt(elem.style.top);

      if (xpos == final_x && ypos == final_y) {
        return true;
      }
      if (xpos < final_x) {
        xpos++;
      }
      if (xpos > final_x) {
        xpos--;
      }
      if (ypos < final_y) {
        ypos++;
      }
      if (ypos > final_y) {
        ypos--;
      }
      elem.style.left = xpos + "px";
      elem.style.top = ypos + "px";
      var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
      elem.movement = setTimeout(repeat,interval);
}

3.setInterval

setInterval -- 间隔指定的毫秒数不停地执行指定的代码
setInterval函数语法:setInterval(codes, interval);

codes -- 代码段的字符串表示(见上),或者是匿名函数、函数名
interval -- 间隔的毫秒数,建议设成30;

每次调用setInterval函数都会产生一个唯一的ID,会重复间隔一段时间执行代码,因此应使用clearInterval函数将其停止

JS DOM编程艺术学习笔记(三)_第1张图片

你可能感兴趣的:(JavaScript)