关于 DOM (文档对象模型)

1. DOM 概念

文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言的标准编程接口。

它是一种与平台和语言无关的应用程序接口(API),它可以动态地访问程序和脚本,更新其内容、结构和 www 文档的风格(目前,HTML 和 XML 文档是通过说明部分定义的)。文档可以进一步被处理,处理的结果可以加入到当前的页面。

DOM 是一 种基于树的 API 文档,它要求在处理过程中整个文档都表示在存储器中。

总结:W3C 已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构、样式。


2. DOM 树

DOM 又称为文档树模型

(1)文档:一个网页可以称为文档,DOM中使用 document 表示

(2)节点:网页中的所有内容都是节点 (标签、属性、文本、注释等),DOM中用 node 表示

(3)元素:网页中的标签,DOM中使用 element 表示

(4)属性:标签的属性

注:DOM 把文档、节点、元素都看作是对象


 DOM 经常进行的操作

(1)获取元素

(2)对元素进行操作(设置其属性或调用其方法)

(3)动态创建元素

(4)事件(什么时机做相应的操作)

3.1.DOM 获取页面元素

获取页面元素

我们想要操作页面上的某部分(显示/隐藏,动画),需要先获取到该部分对应的元素,才进行后续操作。


3.1. 根据 id 获取元素

(1)方法:调用 document 对象的 getElementById 方法。

(2)参数:字符串类型的 id 的属性值。

(3)返回值:对应 id 名的元素对象。

(4)注意1:由于 id 名具有唯一性,部分浏览器支持直接使用 id 名访问元素,但不是标准方式, 不推荐使用。

(5)注意2:代码执行顺序,如果 js 在 html 结构之前,会导致结构未加载,不能获取对应id的元素

<body>
    <p id="para">text</p>
    <p id="para">text1</p>
    <p id="box">text2</p>
    <script>
        // 代码书写顺序:js中获取元素时,必须保证元素已经在浏览器中渲染成功
        // 所以需要将 js 代码写在 html 结构之后
        var para = document.getElementById("para");
        console.log(para); // 输出完整的标签 <p id="para">text</p>
        console.log(typeof para); // object
        
        // 补充:在控制台打印具体的对象,更好的查看里面的属性和方法
        console.dir(para); // p#para  具体的对象
    
        // id 名的唯一性,只会找第一个符合的元素
        para.style.background = "pink"; // 只有第一个text变粉色
    
        // 部分浏览器支持直接使用 id 名访问元素也能实现成功,但不推荐直接使用 id 名
        // box.style.background = "blue";
    </script>
</body>

3.2. 根据标签名获取元素

(1)方法:调用 document 对象的 getElementsByTagName 方法。(普通元素对象也可调用获取内部的元素)

(2)参数:字符串类型的标签名。

(3)返回值:同名的元素对象组成的集合(以伪数组的形式存储)。

(4)注意1:操作数据时需要按照操作数组的方法进行。

(5)注意2:getElementsByTagName 方法内部获取的元素是动态增加的

<body>
    <p>text1</p>
    <p>text2</p>
    <p>text3</p>
    <p>text4</p>
    <div>
        <p>text5</p>
    </div>
    <script>
        var ps = document.getElementsByTagName("p");
          console.log(ps); //  HTMLCollection(5) [p, p, p, p, p]  html元素组成的集合 伪数组
        console.log(ps[0]); // <p style="background: pink;">text1</p>  因为是动态增加的,所以下面添加了背景颜色,这里也会变化
    
        // 遍历:想要依次打印里面的元素对象可以采取遍历的方式
        // 得到的元素对象是动态的(若html元素内容变化,js不用变)
        for (var i = 0; i < ps.length; i++) {
            console.log(ps[i]); // 输出每一项  按照开始标签出现顺序依次排列
        }
        // 操作时按照操作数组的方法进行
        ps[0].style.background = "pink";
    
        // 若页面中只有一个 p,返回的也是伪数组的形式  HTMLCollection [p]
        // 若页面中没有 p,返回的是空的伪数组的形式  HTMLCollection []
    </script>
</body>
<script>
    // 提前获取元素
    var divs = document.getElementsByTagName("div");
    console.log(divs);  // HTMLCollection [] 显示的是空的伪数组 但是后面有添加4个div,因为动态增加,所以里面有4个div
</script>

3.3. 元素对象内部获取标签元素

(1)获取的元素对象内部,本身也可以调用根据标签获取元素方法,例如 div 元素对象也可以调用 getElementsByTagName 方法。

(2)目的:缩小选择元素的范围,类似 css 中的后代选择器

(3)父元素必须是单个对象(必须指明是哪一个元素对象),获取时不包括父元素自己。

<body>
    <div id="box1">
        <p>text1</p>
        <p>text2</p>
    </div>
    <script>
        // var ps1 = document.getElementById("box1").getElementsByTagName("p");
        // 习惯将连续调用方式拆开书写 ***
        var box1 = document.getElementById("box1");
        var ps1 = box1.getElementsByTagName("p");
        console.log(ps1);  // HTMLCollection(2) [p, p]
    
        // 或者是
        var div = document.getElementsByTagName("div");
        var ps1 = div[0].getElementsByTagName("p");  // 通过div[0]拿到第一个div
        console.log(ps1);  // HTMLCollection(2) [p, p]
    </script>
</body>

3.4. 根据 name 获取元素

(1)方法:调用 document 对象的 getElementsByName 方法。

(2)参数:字符串类型的 name 属性值。

(3)返回值:name 属性值相同的元素对象组成的集合(伪数组形式)。

(4)不建议使用:在 IE 和 Opera 中有兼容问题,会多选中 id 属性值相同的元素

<body>
    <form>
        <input type="radio" name="age" />0~10<br />
        <input type="radio" name="age" />11~20<br />
        <input type="radio" name="age" />21~30<br />
    </form>
    <script>
        var ages = document.getElementsByName("age");
        console.log(ages); // NodeList(3) [input, input, input]
        // NodeList  节点列表集合  类数组
        // 方法选中的元素也是动态变化的
    </script>
</body>

3.5. 根据类名获取元素

(1)方法:调用 document 对象的 getElementsByClassName 方法。(普通元素对象也可调用获取内部的元素)

(2)参数:字符串类型的 class 属性值。

(3)返回值:class 属性值相同的元素对象组成的动态集合(伪数组)。

(4)此方法内部获取的元素是动态增加的

(5)浏览器兼容问题:不支持 IE8 及以下的浏览器

<body>
    <div id="box1">
        <p class="para">1</p>
        <p class="para">2</p>
    </div>
    <script>
        var paras = document.getElementsByClassName("para");
        console.log(paras); // HTMLCollection(2) [p.para, p.para]
        // 或者是
        var box1 = document.getElementById("box1");
        var paras = box1.getElementsByClassName("para");
        console.log(paras); // HTMLCollection(2) [p.para, p.para]
    </script>
</body>

3.6. 根据选择器获取元素

(1)方法1:调用 document 对象的 querySelector 方法,通过 css 中的选择器去选取第一个符合条件的标签元素。

(2)方法2:调用 document 对象的 querySelectorAll 方法,通过 css 中的选择器去选取所有符合条件的标签元素集合(伪数组)。

(3)参数:字符串类型的 css 中的选择器。 (例如:.box / #nav)

(4)浏览器兼容问题:不支持 IE8

(5)需要将 js 代码写在 html 结构之后;不会动态增加

<body>
    <div id="box1">
      <p>1</p>
      <p class="para">2</p>
      <p class="para">3</p>
    </div>
    <script>
      var para = document.querySelector("#box1 .para");
      console.log(para); // <p class="para">2</p>

      var paras = document.querySelectorAll("#box1 .para");
      console.log(paras); // NodeList(2) [p.para, p.para]
    </script>
</body>

3.7. 获取特殊元素(body、html)

(1)获取 body 元素

document.body

(2)获取 html 元素

document.documentElement


3.8. 总结

(1)掌握,没有兼容问题

    getElementById()
    getElementsByTagName()

(2)了解

    getElementsByName()
    getElementsByClassName()
    querySelector()
    querySelectorAll()

4.DOM 事件基本应用

JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为,网页中的每个元素都可以产生某些可以触发 JavaScript 的事件。

4.1. 事件

(1)事件:在什么时候做什么事

(2)执行机制:触发–响应机制 (例:轮播图、下拉菜单)

(3)绑定事件(注册事件)三要素:

    事件源:给谁绑定事件
    事件类型:绑定什么类型的事件 (例:click 单击 )
    事件函数:事件发生后执行什么内容,写在函数内部(采用函数赋值形式)

4.2. 事件监听

JavaScript 解析器会给有绑定事件的元素添加一个监听,解析器会一直监测这个元素,只要 触发对应的绑定事件,会立刻执行事件函数。

4.3. 常用事件监听方法

(1)绑定 HTML 元素属性。

<input type="button" id="btn" value="点我有惊喜" onclick="alert('点我做什么')" />

(2)绑定 DOM 对象属性。

<body>
    <input type="button" id="btn" value="点我有惊喜" />
    <script>
      // 获取元素
      var btn = document.getElementById("btn");
      // 添加绑定事件
      btn.onclick = function () {
        // 定义的是事件被触发后要做的事
        alert("惊喜");
      };
    </script>
</body>

4.4. 常用的鼠标事件类型

    onclick → 鼠标左键单击触发
    ondbclick → 鼠标左键双击触发
    onmousedown → 鼠标按键按下触发
    onmouseup → 鼠标按键放开时触发
    onmousemove → 鼠标在元素上移动触发
    onmouseover → 鼠标移动到元素上触发
    onmouseout → 鼠标移出元素边界触发
    onfocus → 获得鼠标焦点触发
    onblur → 失去鼠标焦点触发

5.DOM 元素属性操作

5.1. 非表单元素的属性

例如:href、title、id、src 等。

(1)调用方式:元素对象打点调用属性名,例如 obj.href。

(2)注意:部分的属性名跟关键字和保留字冲突,会更换写法。

    class → className
    for → htmlFor
    rowspan → rowSpan

(3)属性赋值:给元素属性赋值,等号右侧的赋值都是字符串格式。

<body>
    <a href="http://www.baidu.com" id="link">跳转</a>
    <img src="images/a.jpg" class="pic" id="pic" />
    <script>
      var link = document.getElementById("link");
      var pic = document.getElementById("pic");
      console.log(link.href); // http://www.baidu.com
      console.log(link.id); // link id属性值不可以随意更改
      console.log(pic.src); // img 的绝对路径
      console.log(pic.className); // pic 注意获取class采用的是className
      pic.src = "images/b.jpg"; // 赋值时,等号右侧是字符串格式
    </script>
</body>

案例:点击切换图片

<body>
    <input type="button" value="点击" id="btn" /><br />
    <img src="images/a.jpg" id="pic" width="400" height="300" />
    <script>
      var btn = document.getElementById("btn");
      var pic = document.getElementById("pic");
      // 通过一个变量作为判断条件,变量值为 1,认为加载的是 a图片,如果是 2,认为加载的是 b 图片
      var num = 1;
      btn.onclick = function () {
        if (num === 1) {
          pic.src = "images/b.jpg";
          // 数字要对应发生变化
          num = 2;
        } else {
          pic.src = "images/a.jpg";
          num = 1;
        }
      };
    </script>
</body>

案例:点击按钮显示隐藏元素

/* CSS 代码 */
* {
  margin: 0;
  padding: 0;
}
div {
  width: 200px;
  height: 200px;
  background-color: pink;
}
.hide {
  display: none;
}
.show {
  display: block;
}

<!-- html 和 JavaScript 代码 -->
<body>
    <input type="button" value="点击隐藏" id="button" />
    <div id="box"></div>
    <script>
      var btn = document.getElementById("button");
      var box = document.getElementById("box");
      // 通常把样式代码写到 css 中,然后在 js 中调用样式类名进行切换
      btn.onclick = function () {
        // 根据 btn 的 value 值进行条件判断
        // 在事件函数内部有一个 this,指向事件源
        if (this.value === "点击隐藏") {
          box.className = "hide";
          this.value = "点击显示";
        } else {
          box.className = "show";
          this.value = "点击隐藏";
        }
      };
    </script>
</body>

补充:不同函数内部 this 的指向

(1)普通函数 → 指向 window 对象

(2)构造函数 → 指向生成的实例对象

(3)对象的方法 → 指向对象本身

(4)事件函数 → 指向事件源


案例:人物画廊

<!-- html 代码 -->
<h2>人物画廊</h2>
<div id="imagegallery">
    <a href="images/1.jpg" title="人物A">
        <img src="images/1-small.jpg" width="100px" alt="人物1" />
    </a>
    <a href="images/2.jpg" title="人物B">
        <img src="images/2-small.jpg" width="100px" alt="人物2" />
    </a>
    <a href="images/3.jpg" title="人物C">
        <img src="images/3-small.jpg" width="100px" alt="人物3" />
    </a>
    <a href="images/4.jpg" title="人物D">
        <img src="images/4-small.jpg" width="100px" alt="人物4" />
    </a>
</div>

<div style="clear: both"></div>

<img id="image" src="images/placeholder.png" width="450px" />
<p id="des">选择一个图片</p>
/* CSS 代码 */
body {
    background-color: #ccc;
    margin: 1em 10%;
    font-family: "Helvetica", "Arial", serif;
    color: #333;
}
h2 {
    background-color: transparent;
    color: #333;
}
a {
    background-color: transparent;
    color: #c60;
    font-weight: bold;
    text-decoration: none;
}
#imagegallery a {
    display: inline;
    padding: 0px;
    margin-right: 10px;
}
#imagegallery a img {
    border: 0;
}
// js 代码
var imagegallery = document.getElementById("imagegallery");
var links = imagegallery.getElementsByTagName("a");
var image = document.getElementById("image");
var des = document.getElementById("des");

// 遍历数组 添加点击事件
for (var i = 0; i < links.length; i++) {
    links[i].onclick = function () {
        // this 关键字指代的是触发事件的真正事件源,此处写 links[i] 会出错
        image.src = this.href;
        des.innerText = this.title;
        // 取消 a 标签的默认跳转效果
        return false;
    };
}

// for 循环内部添加的绑定事件,在触发时,所有的批量添加事件已经成功,触发事件时都是在循环结束之后
// 批量绑定的事件的事件函数内部如果有 i 变量,要注意,函数执行时已经是在循环结束后
// 循环内部定义的变量是一个全局变量,在循环后执行的 i 变量的值是 i 跳出循环时的值
// 若在循环内写 image.src = links[i].href; 此时的 i 的值是4,所以会出错

5.2. 获取标签内部内容的属性

(1)innerHTML属性,在获取标签内部内容时,如果包含标签,获取的内容会包含标签,获取的内容包括空白换行等。

(2)innerText属性,在获取标签内部内容时,如果包含标签,获取的内容会过滤标签,获取的内容会去掉换行和缩进等空白。

5.3. 更改标签内容

(1)innerHTML 设置属性值,有标签的字符串,会按照 HTML 语法中的标签加载。 (在设置有内部子标签结构时使用)

(2)innerText 设置属性值,有标签的字符串,会按照普通的字符加载。(在设置纯字符串时使用)

<div id="box">
    这是一个 div 标签
    <span>这是一个 span 标签</span>
</div>
<script>
    var box = document.getElementById("box");
    // 调用标签内部内容
    console.log(box.innerHTML);
    /*

    这是一个 div 标签
    <span>这是一个 span 标签</span>

    */
    console.log(box.innerText); // 这是一个 div 标签 这是一个 span 标签

    // 设置标签内部的内容
    //   box.innerHTML = "<h2>Hello JS</h2>";  // 显示二级标题 Hello JS
    box.innerText = "<h2>Hello JS</h2>"; // 显示 <h2>Hello JS</h2>
</script>

总结:innerText 不识别 html 标签,非标准,去除空格和换行。

总结:innerHTML 识别 html 标签,W3C标准,保留空格和换行。


5.4. 表单元素属性

(1)value → 用于大部分表单元素的内容获取(option除外)

(2)type → 可以获取input标签的类型(输入框或复选框等)

(3)disabled → 禁用属性

(4)checked → 复选框选中属性

(5)selected →下拉菜单选中属性

* 注意:在 DOM 中元素对象的属性值只有一个时,会被转成布尔值显示。 例如:txt.disabled = true;

<body>
    <input type="button" value="按钮" id="btn" /><br />
    <input type="text" id="txt" />
    <select id="list">
      <option value="beijing">北京</option>
      <option value="shanghai">上海</option>
    </select>
    <script>
      var btn = document.getElementById("btn");
      var txt = document.getElementById("txt");
      var list = document.getElementById("list");
      var opts = list.getElementsByTagName("option");
      console.log(btn.value); // 按钮
      console.log(txt.type); // text
      console.log(opts[0].innerHTML); // 北京
      console.log(opts[0].value); // beijing
      console.log(list.disabled); // false

      btn.value = "点击";
      txt.value = "请输入内容";

      // 表单元素特有的一些属性,属性名和属性值是一致的,用 true / false 表示
      btn.disabled = true;  // 按钮被禁用
    </script>
</body>

案例:随机设置下拉菜单中的选中项

<body>
    <input type="button" value="选择" id="btn" /><br />
    <select id="food">
      <option>烤肉</option>
      <option>拉面</option>
      <option>小龙虾</option>
      <option>火锅</option>
      <option>麻辣烫</option>
    </select>
    <script>
      var btn = document.getElementById("btn");
      var food = document.getElementById("food");
      var opts = food.getElementsByTagName("option");
      btn.onclick = function () {
          // 每次点击需要获取一个 opts 数组的随即下标
          // Math.random() [0,1)
          // Math.random()*5 [0,5) 向下取整 得到 [0,4]
        var n = Math.floor(Math.random() * opts.length);
        opts[n].selected = true;
      };
    </script>
</body>

案例:搜索文本框

<!-- html 与 js 代码 -->
<body>
    <input type="text" class="gray" value="请输入搜索关键字" id="txtSearch" />
    <input type="button" value="搜索" id="btnSearch" />        <script>
    var txtSearch = document.getElementById("txtSearch");
      // 获得焦点 onfocus 时,如果文本框内容是默认内容,需要清空文字,让文字加载黑色
      txtSearch.onfocus = function () {
        if (this.value === "请输入搜索关键字") {
          this.value = "";
          this.className = "black";
        }
      };
      // 失去焦点 onblur 时,如果文本框内容为空,需要改为默认提示内容,让文字颜色变为灰色
      txtSearch.onblur = function () {
        // 如果用户输入的内容与默认提示文本相同,失去焦点时,文字颜色也要变成灰色
        if (this.value === "" || this.value === "请输入搜索关键字") {
          this.value = "请输入搜索关键字";
          this.className = "gray";
        }
      };
    </script>
</body>
/* CSS 代码 */
.gray {
    color: gray;
}
.black {
    color: black;
}

案例:全选与反选

<!-- html 和 js 代码 -->
<body>
    <div class="wrap">
      <table>
        <thead>
          <tr>
            <th>
              <input type="checkbox" id="all" />
            </th>
            <th>商品</th>
            <th>价钱</th>
          </tr>
        </thead>
        <tbody id="tb">
          <tr>
            <td>
              <input type="checkbox" />
            </td>
            <td>iPhone8</td>
            <td>8000</td>
          </tr>
          <tr>
            <td>
              <input type="checkbox" />
            </td>
            <td>iPad Pro</td>
            <td>5000</td>
          </tr>
          <tr>
            <td>
              <input type="checkbox" />
            </td>
            <td>iPad Air</td>
            <td>2000</td>
          </tr>
          <tr>
            <td>
              <input type="checkbox" />
            </td>
            <td>Apple Watch</td>
            <td>2000</td>
          </tr>
        </tbody>
      </table>
      <input type="button" value="  反 选  " id="btn" />
    </div>
    <script>
      var all = document.getElementById("all");
      var tb = document.getElementById("tb");
      var tb_inputs = tb.getElementsByTagName("input");
      var btn = document.getElementById("btn");
      // 1.全选:让子选项的选择效果始终与全选保持一致
      all.onclick = function () {
        // 遍历所有的子选项
        for (var i = 0; i < tb_inputs.length; i++) {
          tb_inputs[i].checked = all.checked;
        }
      };

      // 2.单独选择子选项过程
      // 给每一次点击任何一个子选项进行判断
      for (var i = 0; i < tb_inputs.length; i++) {
        tb_inputs[i].onclick = function () {
          // 需要判断所有的子选项是否都是选中的状态,如果都选中,让全选被选中,如果有的没有被选中,让全选取消选择
          allChecked();
        };
      }

      // 3.反选
      btn.onclick = function () {
        // 让所有子选项与之前的状态相反
        for (var i = 0; i < tb_inputs.length; i++) {
          tb_inputs[i].checked = !tb_inputs[i].checked;
        }
        // 控制全选效果,也需要进行取反
        allChecked();
      };
      // 定义一个 all 是否被选中的函数
      function allChecked() {
        // 使用一个中间过渡变量,初始认为所有的子选项都是被选中的
        var isAllChecked = true;
        // 遍历所有子选项,进行判断
        for (var j = 0; j < tb_inputs.length; j++) {
          // 一旦有一个是没有被选择的,让变量变为 false
          if (tb_inputs[j].checked === false) {
            isAllChecked = false;
            // 只要走到这里,说明肯定不是全选,不需要往下执行循环
            break;
          }
        }
        // 如果循环内部条件永远不成立,说明所有子选项都是被选中,isAllChecked 的值没有发生变化,还是 true
        // 给 all 元素设置 checked 属性
        all.checked = isAllChecked;
      }
    </script>
</body>
/* CSS 代码 */
* {
  margin: 0;
  padding: 0;
}
.wrap {
  width: 300px;
  margin: 100px auto 0;
}
table {
  width: 300px;
  border: 1px solid #c0c0c0;
  border-collapse: collapse;
  border-spacing: 0;
}
th,
td {
  padding: 10px;
  border: 1px solid #d0d0d0;
  color: #404060;
}
th {
  background-color: #09c;
  color: #fff;
  font: bold 16px "微软雅黑";
}
td {
  font: 14px "微软雅黑";
}
tbody tr {
  background-color: #f0f0f0;
}
tbody tr:hover {
  cursor: pointer;
  background-color: #fafafa;
}

5.5. 自定义属性操作

(1)getAttribute(name) → 获取标签行内属性

(2)setAttribute(name,value) → 设置标签行内属性

(3)removeAttribute(name) → 移除标签行内属性

(4)与element.属性的区别: 上述三个方法用于获取任意的行内属性,包括自定义的属性。

(5)注意:

    以上方法的参数都是字符串格式。
    setAttribute 中传的参数 name 不需要进行属性名的修改,因为参数是字符串格式,和标识符不会有冲突。(例如:class 写作 class 就好,不用写成 className)

<body>
    <div id="box" age="18" sex="male">小明</div>
    <script>
      var box = document.getElementById("box");
      // 获取元素自有属性
      console.log(box.id); // box

      // 获取自定义属性,自定义属性不能直接打点调用
      console.log(box.getAttribute("age")); // 18
      // 此方法也可以调用自有属性
      console.log(box.getAttribute("id")); // box

      // 设置属性,添加新的自定义属性或自有属性
      box.setAttribute("age", "20");
      box.setAttribute("city", "beijing");
      // 传的参数不需要进行属性名的修改,因为参数是字符串格式,和标识符不会有冲突
      box.setAttribute("class", "demo");

      // 移除属性
      box.removeAttribute("age");
      box.removeAttribute("class");
    </script>
  </body>

补充:可以定义一个获取元素的函数,之后调用即可

function my$(id){
    return document.getElementById(id);
}
// 存入变量中的原因:只调用一次函数,这个对象就可以反复使用
var btn = my$("btn");  // 获取 id 名为 btn 的元素

5.6. style 样式属性操作

element.style (样式修改比较少或功能简单时使用)

(1)使用 style 属性方式设置的样式显示在标签行内。

(2)element.style 属性的值,是所有行内样式组成的一个样式对象。 (外联式和内嵌式获取不到)

(3)样式对象可以继续点语法调用或更改 css 的行内样式属性,例如 width、height 等属性。

(4)注意1:类似 background-color 这种复合属性的单一属性写法,是由多个单词组成的,要修改为驼峰命名方式书写 backgroundColor。

(5)注意2:通过样式属性设置宽高、位置的属性类型是字符串,需要加上 px 等单位

<body>
    <div id="box" style="width: 100px" class="bg">文字</div>
    <script>
      var box = my$("box");
      // 元素对象的 style 属性的值是一个行内样式组成的对象,对象内部封装了所有的行内的样式属性及属性值
      console.log(box.style);
      // 元素的 style 属性对象可以继续打点调用,获取或设置相关的行内样式属性
      console.log(box.style.width);  // 100px
      console.log(box.style.backgroundColor); // 输出为空
      box.style.width = "300px";  
    </script>
  </body>

5.7. className 样式属性操作

element.className (样式修改比较多或功能复杂时使用)

(1)修改元素的 className 属性相当于直接修改标签的类名。

(2)如果需要修改多条 css 样式,可以提前将修改后的样式设置到一个类选择器中,后续通过 修改类名的方式,批量修改 css 样式

test.onclick = function () {
    this.className = "first change";
    // 多类名选择器:保留原先类名first,加上修改后的类名change(样式写在CSS代码中)
};

注:className 会直接更改元素的类名,会覆盖原先的类名,若要保留,则使用多类名选择器。


案例:显示隐藏二维码

<body>
    <div class="box" id="box">
      <div class="erweima hide" id="er">
        <img src="images/456.png" alt="" />
      </div>
    </div>
    <script>
      var box = document.getElementById("box");
      var er = document.getElementById("er");
      // 鼠标移上事件
      box.onmouseover = function () {
        // er.className = "erweima show";
        er.className = er.className.replace("hide", "show");
      };
      // 鼠标离开事件
      box.onmouseout = function () {
        // er.className = "erweima hide";
        er.className = er.className.replace("show", "hide");
      };
    </script>
</body>
/* CSS 代码 */
.box {
    position: fixed;
    right: 10px;
    top: 40%;
    width: 50px;
    height: 50px;
    background: url(images/bgs.png) no-repeat -159px -51px;
}
.erweima {
    position: absolute;
      top: 0;
      left: -150px;
}
.hide {
      display: none;
}
.show {
      display: block;
}

5.8. 排他思想(算法)

若有同一组元素,我们想要某一个元素实现某种样式,其他不需要,则用到循环的排他思想算法

    所有元素全部清除样式
    给当前元素设置样式
    注意顺序不能颠倒,首先 for 循环排除所有,再设置自己

案例:文本框高亮显示

// js 代码
// 获取所有input文本框
var txts = document.getElementsByTagName("input");
for (var i = 0; i < txts.length; i++) {
      // 排他思想:1.排除其他 2.保留自己
      txts[i].onfocus = function () {
    // 排除其他的方法:将所有的项包含自己都设置为默认样式
    // 遍历数组,让所有的样式恢复默认
    for (var j = 0; j < txts.length; j++) {
        txts[j].style.backgroundColor = "";
    }
    // 保留自己的特殊样式
    this.style.backgroundColor = "pink";
  };
}

案例:开关灯案例

<!-- 第一种方法  -->
<body>
    <input type="button" value="关灯" id="btn" />
    <script>
      var btn = document.getElementById("btn");
      // 定义一个判断变量,true 表示开灯状态,false 表示关灯状态
      var flag = true;
      btn.onclick = function () {
          if (flag) {
            document.body.style.backgroundColor = "#000";
            this.value = "开灯";
            flag = false;
          } else {
            document.body.style.backgroundColor = "#fff";
            this.value = "关灯";
            flag = true;
          }
      };
    </script>
</body>

<!-- 第二种方法  -->
  <body>
    <input type="button" value="关灯" id="btn" />
    <script>
      var btn = document.getElementById("btn");
      btn.onclick = function () {
        if (this.value === "关灯") {
          document.body.style.backgroundColor = "#000";
          this.value = "开灯";
        } else {
          document.body.style.backgroundColor = "#fff";
          this.value = "关灯";
        }
      };
    </script>
</body>

 

案例:表格隔行变色和高亮显示

表格 table 分为 thead 和 tbody,变色只有 tbody ,第一行 thead 不参与,所以只有 tbody 里的行 tr 变化。

// 获取 tbody
var tb = document.getElementById("tb");
// 获取 tbody 里的所有的 tr
var trs = tb.getElementsByTagName("tr");
// 1.隔行变色
for (var i = 0; i < trs.length; i++) {
      // 下标为偶数的行显示粉色
      // 下标为奇数的行显示灰色
    if (i % 2 == 0) {
    trs[i].style.backgroundColor = "pink";
    } else {
        trs[i].style.backgroundColor = "lightgray";
    }
    // 全局变量
    var bgc;
    // 鼠标移上高亮显示
    trs[i].onmouseover = function () {
        // 定义变量记录 tr 原来的颜色
        bgc = this.style.backgroundColor;
        this.style.backgroundColor = "skyblue";
    };
    // 鼠标离开恢复默认
    trs[i].onmouseout = function () {
        this.style.backgroundColor = bgc;
    };
}

案例:tab 选项卡切换

<body>
    <div class="box">
      <div class="hd" id="hd">
        <span class="current">体育</span>
        <span>娱乐</span>
        <span>新闻</span>
        <span>综合</span>
      </div>
      <div class="bd" id="bd">
        <div class="current">我是体育模块</div>
        <div>我是娱乐模块</div>
        <div>我是新闻模块</div>
        <div>我是综合模块</div>
      </div>
    </div>
    <script>
      var hd = document.getElementById("hd");
      var spans = hd.getElementsByTagName("span");
      var bd = document.getElementById("bd");
      var divs = bd.getElementsByTagName("div");
      // 鼠标移上某个 span ,让它添加一个类名,其他的失去类名
      for (var i = 0; i < spans.length; i++) {
        // 给每个span添加一个新属性,用来记录自己在数组中的下标
        // spans[i].setAttribute("index", i);
        spans[i].index = i;
        spans[i].onmouseover = function () {
          // 排他思想
          for (var j = 0; j < spans.length; j++) {
            spans[j].className = "";
            // 由于 divs 中数据个数与 spans 一样,所以可以在同一个遍历循环中,进行排他操作
            divs[j].className = "";
          }
          // 保留自己
          this.className = "current";
          // 对应控制思想:有两组数据中存储了相同个数的元素对象,一组对象的变化,会引起另外一组的变化
          // 实现方法:找两个数据中的共同点,两个数组中元素对象的下标是一样的
          // 对应控制中也会涉及到排他操作
          // 保留div自己的类名
          // var index = this.getAttribute("index");
          // divs[index].className = "current";
          divs[this.index].className = "current";
        };
      }
    </script>
</body>

/* css 代码 */
* {
  margin: 0;
  padding: 0;
}
.box {
  width: 400px;
  height: 300px;
  border: 1px solid #ccc;
  margin: 100px auto;
}
.box .hd {
  height: 45px;
}
.hd span {
  display: inline-block;
  width: 90px;
  height: 100%;
  background-color: pink;
  line-height: 45px;
  text-align: center;
}
.hd span.current {
  background-color: skyblue;
}
.bd div {
  display: none;
  height: 255px;
  background-color: skyblue;
}
.bd div.current {
  display: block;
}

5.9. H5 自定义属性

目的:为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中

因为有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性,所以H5新增了自定义属性

(1)设置 H5 自定义属性

H5 规定自定义属性 data- 开头作为属性名并且赋值

    <div data-index="1"></div>

    或者在 JS 中设置 div.setAttribute("data-index",2);

(2)获取 H5 自定义属性

    兼容性获取:`element.getAttribute(“data-index”)(兼容性好)
    H5 新增:element.dataset.index / element.dataset["index"](IE11 才开始支持)(只能获取 data- 开头,dataset 是一个集合,里面存放了所有以 data 开头的自定义属性 )

注:如果自定义属性里面有多个 - 连接的单词,获取时采取驼峰命名法

<div data-list-name="andy"></div>
<script>
    console.log(div.getAttribute("data-list-name"));
    console.log(div.dataset.listName);
    console.log(div.dataset["listName"]);
</script>


 

  • 31
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值