CSS属性操作


 

CSS属性操作
指,用JavaScript来操作一个元素的CSS样式, 有2种方式
获取CSS属性值
设置CSS属性值


getComputedStyle()方法 获取CSS属性的取值
语法:getComputedStyle(obj).attr
obj DOM对象,也就是通过getElementById()  getElementsByTagName() 获取的元素节点
attr CSS属性名,这里是属性名使用的是 “骆驼峰型” 的CSS属性名,
如,font-size 写成 fontSize      border-bottom-width 写成borderBottomWidth
getComputedStyle() 有兼容性,支持Google  Firefox  和 IE9及以上
不支持IE6  IE7 和 IE8 (可以使用currentStyle 来实现兼容)

 例子,获取颜色

  <style>
    #box {
      width: 200px;
      height: 200px;
      background-color: green;
    }
  </style>

    window.onload = function () {
      var oBtn = document.getElementById("btn");
      var oBox = document.getElementById("box");
      oBtn.onclick = function () {
        //alert(getComputedStyle(oBox).backgroundColor);
        //与下面的写法是等价的 凡是对象的属性都有这两种写法
        //如,document.getElementById("btn")写成document["getElementById"]("btn")
        //如,oBtn.id写成oBtn["id"]     
        alert(getComputedStyle(oBox)["backgroundColor"]);
      }
    }

  <input id="btn" type="button" value="获取颜色" />
  <div id="box"></div>

设置CSS属性值
2种实现方式,
style对象
cssText()方法

style对象,在元素的style属性来添加样式,这个设置的是"行内样式"
语法:obj.style.attr="值";
obj 是DOM对象    attr 是CSS属性名 也是采用 骆驼峰 型

obj.style.attr 等价于 obj.style["attr"]
如:oDiv.style.width 等价于 oDiv.style["windth"]

 
使用style来设置CSS属性,最终是在元素的style属性添加

 <style>
    #box {
      width: 200px;
      height: 200px;
      background-color: green;
    }
  </style>


    window.onload = function () {
      var oBtn = document.getElementById("btn");
      var oBox = document.getElementById("box");
      oBtn.onclick = function () {
        var attr = document.getElementById("attr").value;
        var val = document.getElementById("val").value;
        //获取的文本框value值 其实是字符串,也就是说变量attr 和 val字符串来的
        //所有不能使用obj.style.attr的方式来设置CSS属性
        //而是必须使用obj.style[attr]
        oBox.style[attr] = val;

        //如果还想为同一个元素添加多个样式 如下面宽 高 设置后会覆盖之前设置的宽高
        //但用style来实现 就需要一个个来写,很不高效
        oBox.style.width = "300px";
        oBox.style.height = "300px";
      }
    }

  属性:<input id="attr" type="text" /><br />
  取值:<input id="val" type="text" /><br />
  <input id="btn" type="button" value="设置颜色" />
  <div id="box"></div>
 
在实际中 如果为一个元素同时设置多个CSS属性,更倾向使用HTML属性的方式给元素加上一个class属性,从而把样式整体给元素添加上
 <style>
    .oldbox {
      width: 100px;
      height: 100px;
      background-color: blue;
    }

    .newbox {
      width: 50px;
      height: 50px;
      background-color: green;
    }
  </style>

    window.onload = function () {
      var oBtn = document.getElementById("btn");
      var oBox = document.getElementById("box");
      oBtn.onclick = function () {
        oBox.className = "newbox";
      }
    }

  <input id="btn" type="button" value="切换">
  <div id="box" class="oldbox"></div>
 


获取CSS属性值,不可以用obj.style.attr 或 obj.cssText.arr,而一定要用getComputedStyle()
//内嵌样式
<style>
    #box {
      width: 100px;
      height: 100px;
      background-color: blue;
    }
  </style>

    window.onload = function () {
      var oBtn = document.getElementById("btn");
      var oBox = document.getElementById("box");
      oBtn.onclick = function () {
        //对话框的内容是空的
        //因为obj.style.attr 只可获取元素styl属性中设置的CSS属性
        alert(oBox.style.width);
      }
    }

  <input id="btn" type="button" value="获取宽度">
  <div id="box"></div>
 
 使用行内样式,点击按钮后,就可获取宽度
  window.onload = function () {
      var oBtn = document.getElementById("btn");
      var oBox = document.getElementById("box");
      oBtn.onclick = function () {
        alert(oBox.style.width);
      }
    }

  <input id="btn" type="button" value="获取宽度">
  <div id="box" style="width:100px;height:100px;background-color: blue;"></div>
 
使用getComputedStyle()没有行内设置,只有内嵌样式,也能获取到widtn
 <style>
    #box {
      width: 100px;
      height: 100px;
      background-color: blue;
    }
  </style>

    window.onload = function () {
      var oBtn = document.getElementById("btn");
      var oBox = document.getElementById("box");
      oBtn.onclick = function () {
        alert(getComputedStyle(oBox).width);//100px
      }
    }

  <input id="btn" type="button" value="获取宽度">
  <div id="box"></div>

从名字可以看成 get Computed style (获取计算后的样式)
计算后的样式 :就是不管是内嵌样式 还是行内样式 最终获取的是根据CSS优先级计算后的结果,

如下面的例子中,由于使用了!important ,根据CSS优先级的计算 box的宽度为150px,
如果用oBox.style.width获取的结果却是100px ,我们都知道这是不正确的
 <style>
    #box {
      width: 150px !important;
    }
  </style>

    window.onload = function () {
      var oBtn = document.getElementById("btn");
      var oBox = document.getElementById("box");
      oBtn.onclick = function () {
        var width = getComputedStyle(oBox).width;
        alert("元素的宽度为" + width);
      }
    }

  <input id="btn" type="button" value="获取宽度">
  <div id="box" style="width:100px;height:100px;background-color: blue;"></div>

 




结构层 html结构
表示层 css装饰
行为层 交互特效

文档里的每个元素都是一个对象,每个元素都有一个style属性,也是一个对象
每个对象又有各种各样的属性
有些属性告诉我们 元素在节点树上 的位置信息,如parentNode nextSibling previousSibling childNodes firstChild 和 lastChild 这些属性告诉我们文档中个节点之间关系信息
nodeType 和 nodeName属性 包含元素本身的信息,如对某个元素的nodeName属性进行查询 将返回一个 诸如"p" 之类的字符串
每个元素都有一个style属性 ,包含着元素的样式,属性的返回值是对象而不是字符串
element.style.property

利用typeof 来验证style属性 确实是一个对象
window.onload = function () {
      var para = document.getElementById("example");
      alert(typeof para.nodeName); //string 字符串
      alert(typeof para.style); //object 对象
    }

  <p id="example" style="color:green;font-family:sans-serif;font-weight: bold;">这是一个段落</p>
 
获取样式,
如想获取颜色 则需使用style对象的color属性
element.style.color
如想获取字体 则需要使用style对象的fontFamily属性
element.style.fontFamily 不能写成element.style.font-family 会报错,中间那一横会解释为减法运算 ,必须要用驼峰的写法fontFamily

 

  window.onload = function () {
      var para = document.getElementById("example");
      alert(para.style.color);
      alert(para.style.fontFamily);
      alert(para.style.fontWeight);
    }

  <p id="example" style="color:green;font-family:sans-serif;font-weight: bold;">这是一个段落</p>

 DOM能够解析CSS速记属性 如font

    window.onload = function () {
      var para = document.getElementById("example");
      alert(para.style.fontSize);
      alert(para.style.fontFamily);
    }

  <p id="example" style="font:12px 'Arial',sans-serif;">这是一个段落</p>

 

只有把CSS style属性插入到标记里,才可以用DOM style属性那些信息
但这样做,结构和样式会混杂在一起,

样式与结构分离 ,用一个外部样式表去设置样式 ,在文件开头部分 加上一个link元素 并指向style.css文件
DOM style 属性不能检索在外部CSS文件里声明的样式 ,弹出的是空白

 <style>
    p#example {
      color: orange;
    }
  </style>

    window.onload = function () {
      var para = document.getElementById("example");
      //DOM style提取不到这样设置的样式
      //在外部样式表里声明的样式不会进入style对象,在文档<head>部分里声明的样式也一样
      alert(para.style.color);
    }

  <p id="example">这是一个段落</p>

设置样式
style对象的各个属性都是可读写的,,不仅可通过某个元素的style属性去获取样式,也可用赋值操作来更新样式
element.style.property = value;

style对象的属性值永远是一个字符串,对象的属性值必须放在引号里,单 双 引号都可以
如果忘记引号会把等号右边的值解释为一个变量,设置的属性值会覆盖那些内嵌在标记里的CSS代码,
用赋值操作符可以设置任何一种样式属性如font 的速记属性也是可以的
para.style.font="2em 'Times',serif“;

 

 window.onload = function () {
      var para = document.getElementById("example");
      para.style.color = "blue"; //原来的绿色设置成了蓝色
    }
  <p id="example" style="color:green;font-weight: bold;">这是一个段落</p>

 



DOM设置样式很容易,但您能做什么事并不意味着您应该做什么事
何时该用DOM脚本设置样式,绝大多数场合 还是应该用CSS去声明样式

就像不应该利用DOM去创建重要的内容,那也不应该用DOM为文档设置重要的样式

何时该用DOM脚本设置样式
根据元素在节点树里的位置来设置样式

通过css声明样式的具体做法有三种
1 标签元素,如p元素 统一的声明样式
p{ font-size:1em;}

2 有特定的class属性的所有元素单独的声明的样式
.fineprint{font-size:.8em;}

3 为有独一无二的id属性的元素单独声明样式
#intro{font-size:1.2em;}

4 也可为有类似属性的多个元素声明样式
input[type*="text"]{font-size:1.2em;}

5 在现代浏览器中,可根据元素的位置声明样式
p:first-of-type{
     font-size:1em;
     font-weight:bold;
}

还有CSS2的 如  :first-child 和 :last-child
还有CSS3的 如  :nth-child() 和 nth-of-type()之类的位置选择器
但 在文档的节点树中 为特定位置的某个元素应用样式也是很难的
如css3中可使用 h1~*选择器为所有h1元素的 下一个同辈元素声明样式,但又的浏览器不支持CSS3的这些位置选择器
 
如下面这个例子,利用DOM很轻松的找到文档中的所有h1元素,也能找出紧跟在每个h1 元素后面的那个元素,并添加样式

 <script src="./scripts/addLoadEvent.js"></script>
  <script src="./scripts/styleHeaderSiblings.js"></script>

  <h1>这是段落一的标题</h1>
  <p>段落一里的文字</p>
  <p>段落一里的文字</p>
  <p>段落一里的文字</p>

  <h1>这是段落二的标题</h1>
  <p>段落二里的文字</p>
  <p>段落二里的文字</p>

 styleHeaderSiblings.js
function styleHeaderSiblings() {
  //检查浏览器能否理解我们在这个函数里用到的DOM方法
  if (!document.getElementsByTagName) return false;
  //用getElementsByTagName()方法把所有的h1元素找出来
  var headers = document.getElementsByTagName("h1");
  var elem;
  //遍历这个节点集合里所有元素
  for (var i = 0; i < headers.length; i++) {
    //文档中的下一个节点可以用nextSibling属性查找出来  headers[i].nextSibling 
    //这里真正需要的是不是下一个节点,而是下一个元素节点 
    //把当前h1元素(即headers[i])的nextSibling节点作为参数传递给 getNextElement函数
    //并把函数调用的返回值赋值给elem变量
    elem = getNextElement(headers[i].nextSibling);
    //给元素设置样式  
    elem.style.fontWeight = "bold";
    elem.style.fontSize = "1.2em";
    elem.style.color = "red";
  }
}

//声明getNextElement函数 参数为node节点
function getNextElement(node) {
  //如果node节点类型与1相等为真。
  //即node节点为元素节点 则退出函数,函数取值为node
  //如果node节点类型不等于1,则继续执行下面的语句
  if (node.nodeType == 1) {
    return node;
  }
  //如果node节点的下一个兄弟节点存在即条件为真,
  //则退出函数 并递归 参数变为node节点的下一个兄弟节点
  //从一个函数的内部 调用函数本身叫做递归调用
  if (node.nextSibling) {
    return getNextElement(node.nextSibling);
  }
  //如果node节点的下一个兄弟节点不存在即条件为假 则继续执行下面的语句
  //退出函数 函数取值为null
  return null;
}
//用window.onload事件调用这个函数,
//window.onload = styleHeaderSiblings();
//最好是用addLoadEvent函数 来调用,可绑定更多的函数到这个事件上
addLoadEvent(styleHeaderSiblings);
 addLoadEvent.js
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function () {
      oldonload();
      func();
    }
  }
}
根据某种条件反复设置某种样式
表格数据,让表格里的行更可读的常用技巧是交替改变他们的背景色,形成斑马线效果
通过设置奇数 和 偶数 行样式的办法实现这种效果,如果浏览器支持css3 只需2行样式
tr:nth-child(odd){background-color:#ffc;}
tr:nth-child(even){background-color:#fff;}

如果nth-child()不能用,也可为表格中每个奇数行(或偶数行) 设置一class属性即可
但这方法不方便,如果将来要在表格中插入或删除一行,那会很痛苦的手动更新class属性

 

 <style>
    body {
      background-color: #fff;
      color: #000;
      font-family: sans-serif;
    }

    table {
      border: solid red 1px;
      margin: auto;
    }

    caption {
      padding: .2em;
      font-size: 1.2em;
    }

    th,td {
      width: 10em;
      padding: .5em;
    }

    th{
      text-align: left;
      font-weight: normal;
      border: 1px dotted #699;
      background-color: #9cc;
    }

    /* 
    用CSS3方法实现只需2行样式
    tr:nth-child(odd){background-color: pink;}
    tr:nth-child(even){background-color: #fff;} 
    */

    /* 给奇数设置class 颜色 */
    .odd { background-color: red;}
  </style>

  <table>
    <caption>成绩表</caption>
    <thead>
      <tr>
        <th>姓名</th>
        <th>科目</th>
        <th>成绩</th>
      </tr>
    </thead>

    <tbody>
      <tr class="odd">
        <td>小明</td>

        <td>数学</td>
        <td><abbr>66</abbr></td>
      </tr>

      <tr>
        <td>婷婷</td>
        <td>数学</td>
        <td>96</td>
      </tr>

      <tr class="odd">
        <td>嘻嘻</td>
        <td>数学</td>
        <td>86</td>
      </tr>
    </tbody>
  </table>
 
用JavaScript他特擅长处理重复的任务,用一个while 或for循环就可轻松遍历长列表
写一个函数为表格添加斑马线效果,只需要隔行设置样式即可。并且想让某行在鼠标指针悬停其上时其文本变为粗体
1. 把文档里所有的table元素找出来
2. 对每个table元素,创建odd变量并把它初始化false
3. 遍历这个表格里的所有数据行
4. 如果变量odd的值是true,设置样式并把odd变量修改为false
5. 如果变量odd的值是false,不设置样式,但把odd变量修改为true

 <style>
    body {
      background-color: #fff;
      color: #000;
      font-family: sans-serif;
    }

    table {
      border: solid red 1px;
      margin: auto;
    }

    caption {
      padding: .2em;
      font-size: 1.2em;
    }

    th,td {
      width: 10em;
      padding: .5em;
    }

    th {
      text-align: left;
      font-weight: normal;
      border: 1px dotted #699;
      background-color: #9cc;
    }
  </style>
  <script src="./scripts/addLoadEvent.js"></script>
  <script src="./scripts/stripeTables.js"></script>
</head>

<body>
  <table>
    <caption>成绩表</caption>
    <thead>
      <tr>
        <th>姓名</th>
        <th>科目</th>
        <th>成绩</th>
      </tr>
    </thead>

    <tbody>
      <tr class="odd">
        <td>小明</td>

        <td>数学</td>
        <td><abbr>66</abbr></td>
      </tr>

      <tr>
        <td>婷婷</td>
        <td>数学</td>
        <td>96</td>
      </tr>

      <tr class="odd">
        <td>嘻嘻</td>
        <td>数学</td>
        <td>86</td>
      </tr>
    </tbody>
  </table>
stripeTables.js
function stripeTables() {
  //检查浏览器是否支持函数中用到哪些DOM方法
  if (!document.getElementsByTagName) return false;
  //文档中的所有table元素都找出来
  var tables = document.getElementsByTagName("table");
  var odd, rows;
  //对每一个table元素,创建odd变量并初始化为false
  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) {
        //如果变量odd的值是true,设置样式并把odd变量修改为false
        rows[j].style.backgroundColor = "pink";
        odd = false;
      } else { //如果变量odd的值是false,不设置样式,但把odd变量修改为true
        odd = true;
      }
    }
  }
}
//window.onload = stripeTables();
addLoadEvent(stripeTables);


 只要有可能,最好选用css设置样式,如果css力不从心的场合,就用需要帮忙,

但是何时用CSS来设置样式,何时用DOM设置样式 不是很容易的,如果涉及到根据某个事件来改变样式 就更难了
CSS提供的:hove等伪类class属性允许根据HTML元素的状态来改变样式
DOM 也可通过onmouseover等事件对HTML元素的状态变化做出响应
很难判断何时用:hover属性,何时用onmouseover事件
最简单的答案是 选择最容易实现的方法,
例如:如果只想让连接在鼠标指针悬停在其上时,改变颜色就用CSS
a:hover{color:#c60;}
    如果想用这个伪类在鼠标指针悬停在其他元素上时改变样式,支持这做法的浏览器不是很多

总之需要决定纯使用CSS来解决,还是利用DOM来设置样式 需要考虑下吗两点
1,这个问题最简单的解决方案是什么
2,那种解决方案会得到更多浏览器的支持
如果想改变某个元素的呈现效果使用CSS
如果想改变某个元素的行为用DOM

例如上面这个例子中的表格,我想让某行在鼠标指针悬停在上面的时候,其文本变粗
可以用css,但设置了后 这个效果只能一部分浏览器里看到,理论上是鼠标悬停在哪一行,哪一行文本就会加黑加粗
tr:hover{font-weight:bold}

 

下面用DOM来解决,命名一个highlightRows()








 



















posted @ 2020-12-23 16:14  沁莹  阅读(347)  评论(0)    收藏  举报