DOM (一)

146 阅读6分钟

1、定义

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

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

2、DOM树

  • 文档:一个页面就是一个文档,DOM中使用document表示

  • 元素:页面中的所有标签都是元素,DOM中使用element表示

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

  • DOM把以上内容都看作是对象,有自己的属性和方法

image.png

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
</body>
</html>

3、获取页面元素

DOM在实际开发中主要用来操作元素,要操作元素首先要获取元素。

3.1根据ID获取

document.getElementById

​ getElementById()返回一个匹配特定 ID的元素。由于元素的 ID 在大部分情况下要求是独一无二的,这个方法自然而然地成为了一个高效查找特定元素的方法

​ 如果需要查找到那些没有 ID 的元素,你可以考虑通过 CSS 选择器使用 querySelector()

​ 语法:

var element = document.getElementById(id);

​ 参数:element是一个 Element 对象。如果当前文档中拥有特定 ID 的元素不存在则返回 null.

id是==大小写敏感的字符串==,代表了所要查找的元素的唯一 ID.

​ 返回值:返回一个匹配到 ID 的 DOM Element 对象。若在当前 Document 下没有找到,则返回 null。

应用:
<body>
  <div id="aaa">2020-12-01</div>
  <script>
    // 文档页面从上往下加载,所以先得有标签,所以script要写到标签的下边
    // 括号里的参数必须是字符串,因为id是大小写敏感的字符串,代表了所要查找的元素的唯一ID.
    var timer = document.getElementById('aaa');
    // 返回的是一个元素对象
    console.log(timer);
    console.log(typeof timer);
    //console.dir()打印我们返回的元素对象,更好的查看里面的属性和方法
    console.dir(timer);
  </script>
</body>

3.2根据标签名获取

document.getElementsByTagName

​ 返回一个包括所有给定标签名称的元素的 HTML 集合HTMLCollection。整个文件结构都会被搜索,包括根节点。返回的 HTML 集合是动态的,意味着它可以自动更新自己来保持和 DOM 树的同步而不用再次调用 document.getElementsByTagName()

语法:

var elements = document.getElementsByTagName(name);

​ 参数:elements 是一个由发现的元素出现在树中的顺序构成的动态的 HTML 集合 HTMLCollection (但是看下面的提示) 。

name 是一个代表元素的名称的字符串。特殊字符 "*" 代表了所有元素。

​ 提示:最新的 W3C 规范说明这些元素是 HTMLCollection(HTML 集合;然而,这个方法在 WebKit 内核的浏览器中返回一个 NodeList

注意:

  • 返回的是获取过来元素对象的集合,以==伪数组==的形式存储的;不管页面中有几个li元素,返回的都是为数组

  • 因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历。

  • 得到元素对象是动态的,改变li元素,页面上显示也会发生改变

  • 如果获取不到元素,则返回==为空的伪数组==(因为获取不到对象)

应用:

//打印我们返回的元素对象,更好的查看里面的属性和方法
console.dir()
//还可以获取某个元素(父元素)内部所以指定标签名的子元素
document.getElementsByTagName('标签名');
//不能让伪数组作为父元素,父元素必须要指定的单个父元素
<body>
  <div id="aaa">2020-12-01</div>
  <ul>
    <li>123-0</li><li>123-1</li><li>123-2</li><li>123-3</li><li>123-4</li>
  </ul>
  <ol id="ool">
    <li>456-0</li><li>456-1</li><li>456-2</li><li>456-3</li><li>456-4</li>
  </ol>
  <script>
    // 文档页面从上往下加载,所以先得有标签,所以script要写到标签的下边

    // document.getElementById
    // 括号里的参数必须是字符串,因为id是大小写敏感的字符串,代表了所要查找的元素的唯一ID.
    var timer = document.getElementById('aaa');
    // 返回的是一个元素对象
    console.log(timer);
    console.log(typeof timer);
    console.dir(timer);

    // document.getElementsByTagName
    var lli = document.getElementsByTagName('li');
    // 1、返回的是获取过来元素对象的集合,以伪数组的形式存储的
    console.log(lli);
    console.log(lli[0]);
    // 2、想要依次打印里面的元素对象,我们可以采取遍历的方式
    // 得到的元素对象是动态的,改变li元素,页面上显示也会发生改变
    for (var i = 0; i < lli.length; i++) {
      console.log(lli[i]);
     }

    // 如果页面中只有一个li,返回的是伪数组的形式
    // 如果页面中没有这个元素,返回的是空的伪数组的形式
    // element.getElementsByTagName('标签名')
    var ol = document.getElementsByTagName('ol');
    console.log(ol);
    // 56行报错,因为ol是伪数组,不能让伪数组作为父元素,父元素必须要指定的单个父元素
    console.log(ol.getElementsByTagName('li'));
    // 正确写法,指定ol[0]为父元素
    console.log(ol[0].getElementsByTagName('li'));
    // 一般为父元素写上id,通过id值获取更方便
    var ool = document.getElementById('ool');
    console.log(ool);
    console.log(ool.getElementsByTagName('li'));
  </script>
</body>

3.3通过HTML5新增的方法获取

 // 1.getElementsByClassName根据这些类名获得某些元素集合
    var boxs = document.getElementsByClassName('box');
    console.log(boxs);

    // 2.querySelector 返回指定选择器的第一个元素对象
    // 切记里边的选择器需要加符号,类选择器加.  id选择器加#  
    // 写成.box的原因是:因为要选是哪个选择器,所以加上.就可以判断出是类选择器
    var firstBox = document.querySelector('.box');
    console.log(firstBox);
    // 加上#就会自动判断为id的选择器
    var nav = document.querySelector('#nav');
    console.log(nav);
    var li = document.querySelector('li')
    console.log(li);

    // 3.querySelectorAll()返回指定选择器的所有元素对象集合
    var allBox = document.querySelectorAll('.box');
    console.log(allBox);
    var lis = document.querySelectorAll('li');
    console.log(lis);

3.4特殊元素获取

 <script>
    // 1. 获取body元素
    var bodyEle = document.body;
    console.log(bodyEle);
    console.dir(bodyEle)
    // 2.获取html元素
    var htmlEle = document.documentElement;
    console.log(htmlEle);
  </script>

4、事件基础

4.1事件概述

​ JavaScript使我们有能力创建东陶页面,而事件是可以被JavaScript侦测道德行为。简单理解就是==触发响应机制==

​ 网页中的每个元素都可以产生某些可以触发JavaScript事件,例如,我们可以在用户点击某按钮是产生一个事件,然后去执行某些操作

4.2事件三要素

​ 事件是由三部分组成,分别为事件源、事件类型和事件处理程序,我们也称为事件三要素

例:点击一个按钮,弹出对话框

// 例:点击一个按钮,弹出对话框
    // 1、获得事件源---按钮
    var btn = document.getElementById('btn');
    // 2、事件类型,也就是如何触发?比如鼠标点击(onclick)或鼠标经过等
    // 3、事件处理程序,通过函数复制的方式完成
    btn.onclick = function(){
      alert('qqqq')
    }

4.3 执行事件的步骤

  1. 获取事件源
  2. 注册事件(绑定事件)
  3. 添加事件处理程序(采取函数赋值形式)
    // 执行事件步骤
    // 点击div,控制台输出‘我被选中了’
    // 1.获取事件源
    var btn2 = document.querySelector('#btn2');
    // 2.绑定事件,注册事件
    // div.onclick
    // 3.添加事件处理程序
    btn2.onclick = function(){
      console.log('我被选中了');
    }

5、操作元素

JavaScript 的 DOM 操作可以改变网页内容、结构和样式,我们可以利用 DOM 操作元素来改变元素里面的内容 、属性等。注意以下都是属性。

image.png

5.1 改变元素内容

element.innerText

从起始位置到终止位置的内容,但它去除 html 标签, 同时空格和换行也会去掉。(不解析html标签)

element.innerHTML--经常使用

起始位置到终止位置的全部内容,包括 html 标签,同时保留空格和换行。(W3C标准,解析html标签)

==这两个属性是可读写的,可以获取元素里面的内容==

应用:显示 / 隐藏密码

    var eye = document.getElementById('eye');
    var pwd = document.getElementById('pwd');
    // 如果有按钮需要多次点击,则利用flag变量来当标准记录
    var flag = 0;
    eye.onclick = function(){
      //点击一次后flag一定要变,才能实现切换效果
      if(flag == 0){
        pwd.type = 'text';
        eye.src = 'images/open.png'
        flag = 1;  //赋值操作
      }else{
        pwd.type = 'password'
        eye.src = 'images/close.png'
        flag = 0;
      }
    }

5.2 修改样式属性

可以通过 JS 修改元素的大小、颜色、位置等样式

1. element.style     行内样式操作

2. element.className 类名样式操作

注意

1.JS 里面的样式采取驼峰命名法 比如 fontSize、 backgroundColor

2.JS 修改 style 样式操作,产生的是==行内样式==(如下图所示),它的CSS 权重比较高。Js样式与内嵌样式冲突,与Js样式发生冲突时,以JS样式为主

image.png

5.2.1 二维码的显示和隐藏

利用样式的显示和隐藏完成二维码的显示和隐藏。display:none 隐藏元素 diaplsy:block显示元素

    var btn = document.querySelector('.close-btn');
    var box = document.querySelector('.box');
    btn.onclick = function(){
      box.style.display = 'none';
    }
5.2.1 循环精灵图

image.png

分析:

①首先精灵图图片排列有规律的

②核心思路: 利用for循环 修改精灵图片的 背景位置 background-position

③剩下的就是考验你的数学功底了

④让循环里面的 i 索引号 * 44 就是每个图片的y坐标

    var lis = document.querySelectorAll('li');
    for (var i = 0; i < lis.length; i++) {
      // 让索引号乘以44就是每个li的背景y坐标,index就是我们的y坐标
      // y坐标是负的,通过引引加加来引入坐标
      var index = i * 44;
      lis[i].style.backgroundPosition = '0 -' + index + 'px';
    }
5.2.3 显示隐藏文本框内容

①首先表单需要2个新事件,获得焦点 onfocus ,失去焦点 onblur

②如果获得焦点, 判断表单里面内容是否为默认文字,如果是默认文字,就清空表单内容,将文字颜色变深

③如果失去焦点, 判断表单内容是否为空,如果为空,则表单内容改为默认文字,将文字颜色变浅

    var text = document.querySelector('input');
    text.onfocus = function(){
      if(this.value == '手机'){
        this.value = '';
      }
      this.style.color = 'black'
    }
    text.onblur = function(){
      if(this.value !== '手机'){
        this.value = '手机'
      }
      this.style.color = '#ccc'
    }
5.2.4 使用className修改样式属性

element.style 行内样式操作

element.className 类名样式操作

注意:

  • 如果样式修改较多,可以采取操作类名方式更改元素样式。
  • class因为是个保留字,不能使用this.class,因此使用className来操作元素类名属性
  • className 会直接更改元素的类名,会覆盖原先的类名
  • 多类名选择器:保留原来的类名
<style>
  div{
    width: 200px;
    height: 200px;
    background-color: pink;
  }
  .change{
    background-color: blue;
    margin-top: 20px;
  }
</style>
<body>
  <div>修改样式</div>
  <div>多类名选择器</div>
  <script>
    var divs = document.querySelectorAll('div');
    divs[0].onclick = function(){
      // this.style.backgroundColor = 'blue'
      // 通过className来修改
      // 这样写覆盖了原来的类名
      this.className = 'change'
    }
    divs[1].onclick = function(){
      // 如果想要保留原来的类名,就可以做多类名选择器
      this.className = 'first change'
    }
  </script>
5.2.5 密码框验证信息
    var input = document.querySelector('input');
    var mes = document.querySelector('.message')
    input.onblur = function(){
      if(this.value.length < 6 || this.value.length > 16){
        mes.className = 'message wrong';
        mes.innerHTML = '您输入的位数是错误的'
      }else{
        mes.className = 'message right';
        mes.innerHTML = '输入正确'
      }
    }