【JavaScript】JS中的文档对象模型DOM

【JavaScript】JS中的文档对象模型DOM


文档对象模型 DOM

一、基本概念

01. DOM概述

  • DOM:Document Object Model,文档对象模型
  • 是W3C组织定义的编程接口,通过这些DOM接口可以改变网页的内容、结构和样式
  • DOM树:
    • 文档:一个页面就是一个文档
    • 元素:页面中的所有标签都属于元素
    • 节点:网页中的所有内容都属于节点
  • 针对元素的操作:创建、增、删、改、查、属性操作、事件操作

02. 基本要求

  • 能够说出什么是DOM

  • 能够获取页面元素能够给元素注册事件

  • 能够操作DOM元素的属性

  • 能够创建元素

  • 能够操作DOM节点

  • 能够写出元素注册事件的两种方式能够说出删除事件的两种方式

  • 能够说出DOM事件流的三个阶段

  • 能够利用事件对象完成跟随鼠标案例

  • 能够封装阻止冒泡的兼容性函数

  • 能够说出事件委托的原理

  • 能够说出常用的鼠标和键盘事件


二、【获取元素】的几种方法~~~

获取DOM元素后,返回的是一个对象

01. 根据ID获取元素

  • document.getElementById(" ");ID是唯一的,所以是Element

    <div id="time"> 2020-10-10 </div>
    <div class="animal"> Dog </div>
    
    var time = document.getElementById("time");
    

02. 根据标签名获取元素

  • document.getElementsByTagName(" ");(标签名可以有多个,所以是Elements

    var tagName = document.getElementsByTagName("div");
    
    • 获取的是元素对象的集合
    • 获取过来的元素:以伪数组的形式存储(不管元素是:一个、多个、没有,都是伪数组)
  • element.getElementsByTagName(" ");

    var li = element.getElementsByTagName("ol");	//获取 ol 中的子元素 li
    
    • 获取指定父元素内部的子元素
    • 【注意】父元素必须是单个对象、是唯一的,即必须指明是哪一个元素对象

03. 根据class获取元素(H5新增)

  • document.getElementsByClassName(" ");

    var animal = document.getElementsByClassName("animal");
    

04. 根据选择器获取元素(H5新增)

【注意】这里的选择器同CSS选择器使用方法一样,类名id名都需要加符号

  • doucument.querySelector(" ");

    只会返回指定选择器的第一个元素对象

    var animal = document.querySelector(".animal");		//返回第一个,元素类名为 animal 的,元素
    
  • doucument.querySelectorAll(" ");

    可以返回指定选择器里的所有元素对象

    var div = doucument.querySelectorAll("div");	//返回所有div标签元素
    

05. 获取body和HTML元素

  • 获取body元素:document.body
  • 获取HTML元素:document.documentElement

三、如何【改变元素】?

01. 改变元素内容

(1)innerText
  • 不识别HTML标签
  • 在读取内容时,会跳过空格、换行、HTML标签
  • 在写入内容时,会将**HTML标签(如果有)**一起写入
var p = document.querySelector("p");	//	<p> 没有变化<span>还是没有</span> </P>
//在读取内容时,会跳过元素内部的HTML标签、空格、换行
p.innerText;

//输出结果:没有变化 还是没有
//在写入内容时,会把HTML标签 一起写入内容中
p.innerText("<strong>改变内容</strong>");

//输出结果:<strong>改变内容</strong>

(2)innerHTML
  • 可识别HTMl标签
  • 在读取内容时,会保留页面原有的空格、换行、标签
  • 在写入内容时,会应用HTMl标签(如果有)
var p = document.querySelector("p");	//	<p> 没有变化<span>还是没有</span> </P>
//在读取内容时,会将元素内部的HTML标签、空格、换行一起显示出来
p.innerHTML;

//	输出结果:没有变化<span>还是没有</span>
//在写入内容时,会识别到 HTML 标签并应用
p.innerHTML("<strong>改变内容</strong>");

// 输出结果(加粗的):改变内容

(3)其它
  • 【注意】表单元素form里面的内容是通过元素属性更改的!!!

02. 改变元素属性

(1)内置属性获取
  • element.属性名

    主要获取内置属性,自定义属性无法通过这种方式获取

    • element.属性名 = “属性值”;
    var img = document.getElementById("image");
    
    img.src = "url";
    img.title = "new_title";
    

(2)自定义属性获取
  • (a)兼容性获取:

    • element.getAttribute("属性名");

      主要获取自定义属性

    • element.setAttribute("属性名","属性值");

      设置自定义属性

    • element.removeAttribute("属性名");


  • (b)H5新增:

    H5新增的规定,将以data-开头的属性名作为自定义属性

    • element.dataset.属性名:获取属性,适用于以data-开头的自定义属性,属性名是data-后面的值

      这个方法只能获取以data-开头的,dataset是一个集合,里面存放了所有以data-开头的自定义属性

    • 如果属性有多个-连接的单词,【需要注意】,在获取时,从第二个-开始,需要驼峰命名

      <div data-index="1" data-last-name="demo"> </div>
      
      var div = document.querySelector("div");
                                       
      //获取 data-index 属性
      div.dataset.index;
      
      //获取 data-last-name 属性,驼峰命名
      div.dataset.lastName;
      

03. 改变样式属性

  • element.style

对元素的行内样式进行操作

【注意】:如果样式没有写在行内,是无法通过这种方式获取到的

  • 使用方法:+.属性

    注意属性名是驼峰命名法,且没有分隔符

    element.style.backgroundColor = " ";
    element.style.fontSize = "";
    
  • element.className

对样式文件中的类名样式进行操作

  • 改变当前元素的类名,注意会覆盖原先的类名

  • 可通过拼接字符串的方式添加,避免覆盖

    element.className += " newClassName";  //注意要加空格
    
  • 运用:精灵图的实现方法

    for循环遍历,改变backgroundPosition的属性值


四、如何【操作元素】?

01. 获取元素的另一种方法——利用节点层级关系获取元素

页面中所有内容都是节点

  • (1)基本属性:
    • nodeTypenodeNamenodeValue:节点类型、节点名称、节点值

      元素节点:nodeType为1

      属性节点:nodeType为2

      文本节点:nodeType为3(文本节点包括文字、空格、换行等

  • (2)父级节点:
    • parentNode

    得到离元素最近的父级节点,如果没有则返回null

  • (3)子级节点:
    • childNodes

    获得所有子节点,包含元素节点、文本节点

    • children

    获取所有的子元素节点

    • firstChildlastChild

    获取第一个(最后一个)子节点,不管是文本节点还是元素节点

    • firstElementChildlastElementChild

    获取第一个(最后一个)子元素节点,有兼容性问题 ,IE9以上才支持

    • parentNode.children[0]parentNode.children[parentNode.children.length - 1]

    返回第一个(最后一个)子元素,没有兼容性问题

    parentNode.children返回的是一个伪数组,

    parentNode.children.length - 1:表示最后一个子元素

  • (4)兄弟节点:
    • nextSiblingpreviousSibling

    获取下一个(上一个)兄弟节点,包含元素节点或者文本节点等等

    • nextElementSiblingpreviousElementSibling

    获取下一个(上一个)兄弟元素节点,兼容性问题,IE9以上才支持

    • 解决兼容性问题:自己封装一个函数

    通过判断 nodeType 值,使用第一种方法实现


02. 动态操作元素节点

(1)创建元素节点
  • document.createElement(" ");

    动态创建元素节点


(2)添加元素节点
  • parentNode.appendChild("child");

    在父元素parenrNode的末尾,追加一个子元素child

  • parentNode.insertBefore("child", "指定元素");

    在父元素parenrNode中,将子元素child添加到指定的其它子元素的前面


(3)删除元素节点
  • parentNode.removeChild("child");

(4)复制元素节点
  • node.cloneNode();

    返回调用该方法的节点的一个副本


    如果括号为空,或者false,则为 浅拷贝 ,只复制标签不复制里面的内容

    如果括号为true,则为 深拷贝 ,会同时复制标签和里面的内容


03.【拓展】——三种动态创建元素方法的区别

  • document.writeelement.innerHTMLdocument.createElement()
(1)关于document.write()
  • document.write是直接将内容写入页面的内容流,
  • 如果是在文档流执行完毕后,执行document.write,则会导致页面内容全部重绘
(2)关于element.innerHTML
  • 创建多个元素的效率高,但结构稍微复杂
  • 但通过拼接字符串的方法添加元素到页面中效率很低(字符串的不可变性)
  • 因此,可以通过**数组的方法push()**添加元素,效率最高
(3)关于document.createElement()
  • 创建多个元素的效率低,但结构更清晰
  • 通过appenChild()直接追加子元素到父元素末尾,效率高

五、关于页面元素的【事件】

01.基本概念

(1)基本事件组成
  • 事件三要素:
    • 事件源
      • 被触发事件的对象
    • 事件类型
      • 如何触发事件,如:点击、滑过、键盘输入等
    • 事件处理程序
      • 完成什么事件
  • 关于this
    • this指向的是事件函数调用者
(2)基本事件执行过程
//1. 首先获取事件源元素
var btn = document.getElementById("btn");
//2. 然后 绑定事件(注册事件)
//3. 最后添加事件处理程序
div.onclick = function(){
    alert("触发事件");
}

02. 元素注册事件的两种方式

(1)传统注册方式
  • 利用on开头的事件,如:onclick
  • 唯一性:同一个元素的同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数
(2)addEventListener事件监听
  • (a)语法结构
  • eventTarget.addEventListener(type, listener, useCapture);

    • 将指定的监听器注册到eventTarget(目标对象)上
    • type:事件类型字符串,如clickmousemover
    • listener:事件处理函数,事件发生时,会调用该监听函数
    • useCapture:可选参数,是一个布尔值,默认false
  • (b)注册事件
eventTarget.addEventListener("type",function);
//为目标函数绑定 type 事件,该事件的处理函数是 function

03. 删除事件的方式

(1)传统方式删除事件
  • eventTarget.onclick = null
(2)removeEventListener删除事件
  • eventTarget.removeListener

    eventTarget.removeListener("type",function);
    //移除目标对象的 type 事件,该事件绑定 function 处理函数
    

04. DOM事件流

(1)基本概念
  • 事件流是指:从页面中接收时间的顺序

    • 事件发生时,会在元素节点之间,按照特定的顺序传播,这个传播过程即DOM事件流
(2)阶段概述
(a)捕获阶段
  • 从 DOM 最顶层的节点开始,然后逐级向下传播,到目标元素接收的过程

  • 在逐级向下传播(沉底)中,如果有祖先元素绑定了相同类型事件(如点击事件),那么在触发目标后代元素事件时(点击后),会按照沉底的顺序(从上到下),依次触发事件(点击的事件)

(b)当前目标阶段
(c)冒泡阶段
  • 事件开始时,从目标事件元素开始接收,然后逐级向上传播,到DOM最顶层的节点,这一过程

  • 在逐级向上传播(冒泡)中,如果有祖先元素绑定了相同类型事件(如点击事件),那么在触发目标后代元素事件时(点击后),会按照冒泡的顺序(从下到上),依次触发事件(点击的事件)

(3)其它
  • onclickon开头的事件,只会触发冒泡阶段
    • 【注意】onbluronfocusonmouseenteronmouseleave是没有冒泡阶段的
  • addEventListener可以触发多个阶段
    • useCapture:参数值为true,则为捕获阶段
    • useCapture:参数值为false,则为冒泡阶段

05. 事件对象

(1)概念
eventTarget.onclick = function(event){
    
};
  • 事件发生后,跟事件相关的一系列信息数据集合,都会存放在这个事件对象event里面

    • event对象,代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态等
  • 事件对象只有在有事件时才会存在,它是系统给自动创建的,即不需要传参进去


  • 这个事件对象我们可以自己命名,如 eventevte

  • 事件对象的兼容性问题

    • IE6、7、8,只会识别 window.event

      兼容: e = e || window.event;

(2)事件对象的常用属性和方法
  • e.target:返回触发事件的对象(谁触发的事件,就返回谁)

    • this:返回的是绑定事件的对象(谁绑定的事件,就返回谁)
  • 返回触发事件的类型

    • e.type
  • (a)阻止默认事件
    • 高版本:e.preventDefault()

    • 低版本(IE6、7、8):e.returnValue

      a.onclick = function(e) {
          // 普通浏览器 e.preventDefault();  方法
           e.preventDefault();
          // 低版本浏览器 ie678  returnValue  属性
           e.returnValue;
          // 我们可以利用return false 也能阻止默认行为 
          // 没有兼容性问题
          return false;
      }
      
  • (b)阻止事件冒泡
    • 标准写法:e.stopPropagation()

    • 非标准写法:e.cancelBubble = true

      if(e && e.stopPropagation){
          e.stopPropagation();
      }else{
          window.event.cancelBubble = true;
      }
      
(3) 事件委托(代理、委派)
  • 不需要给每个子节点单独设置事件监听器,而是把事件监听器设置再其父节点上,即把事件委托给了父节点

    因为事件冒泡,点击子节点后,事件会冒泡到父节点上,同样会触发事件,然后可以通过e.target找到是哪一个子节点触发的事件(点击了谁)


    事件委托的作用:只操作了一次DOM


06. 鼠标事件

(1)基本事件
  • onclick:鼠标点击事件

  • onfocus:获得焦点事件

  • onblur:失去焦点事件

  • onmouseover:鼠标经过事件

    • 经过子元素也会触发父元素的事件
  • onmouseenter:鼠标经过事件(不会冒泡)

    • 只有经过盒子本身才触发
  • onmouseout:鼠标离开事件

    • 经过子元素也会触发父元素的事件
  • onmouseleave:鼠标离开事件(不会冒泡)

    • 只有经过盒子本身才触发

  • 阻止链接跳转

    <a href="javascript:void(0);"> 点击不跳转 </a>
    
    <a href="javascript:;"> 点击不跳转 </a>
    

  • 禁用鼠标右键菜单:contextmenu

    e.addEventListener("contextmenu",function(e){
        e.preventDefault();
    });
    
  • 禁止鼠标选中:selectstart

    e.addEventListener("selectstart",function(e){
        e.preventDefault();
    });
    
(2)鼠标事件对象
  • 鼠标坐标

    • e.clientXe.clientY

      得到鼠标相对于 client可视窗口区域的坐标

    • e.pageXe.pageY————(主要)

      得到鼠标相对于页面文档的坐标

    • e.screenXe.screenY

      得到鼠标相对于电脑屏幕的坐标

  • 鼠标移动

    • mousemove

      只要鼠标移动,就触发事件

      document.addEventListener('mousemove', function(e) {
         console.log("X坐标:"+e.pageX+",Y坐标:"+e.pageY);
      });
      

07. 键盘事件

(1)基本事件
  • keyup :按键弹起的时候触发 ,松开键盘时只触发一次

  • keydown :按键按下的时候触发,可识别功能键

    • 按下不松开会一直触发
  • keypress :按键按下的时候触发,不可识别功能键,如ctrlshift、 左右箭头等

    键盘事件的响应顺序:keydown → keypress → keyup

    【注意】三者的区别与应用场景

(2) 键盘事件对象
  • e.keycode:返回对应按键的ASCII码值

    可以判断用户按下了哪一个键

    • keyupkeydown不区分字母大小写,且以大写状态显示键值

    • keypress可以区分字母大小写

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值