【JavaScript】17.文档对象模型补充

175 阅读8分钟

这是我参与8月更文挑战的第29天,活动详情查看:8月更文挑战


文档对象模型补充

01.操作元素

(1)获取元素的另一种方法

  • 利用节点层级关系获取元素

    页面中所有内容都是节点

  • 基本属性:

    • nodeTypenodeNamenodeValue:节点类型、节点名称、节点值

      元素节点:nodeType为1

      属性节点:nodeType为2

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

  • 父级节点:

    • parentNode

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

  • 子级节点:

    • childNodes

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

    • children

      获取所有的子元素节点

    • firstChildlastChild

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

    • firstElementChildlastElementChild

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

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

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

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

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

  • 兄弟节点:

    • nextSiblingpreviousSibling

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

    • nextElementSiblingpreviousElementSibling

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

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

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


(2)动态操作元素节点

  • 创建元素节点

    • document.createElement(" ");

    动态创建元素节点

  • 添加元素节点

    • parentNode.appendChild("child");

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

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

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

  • 删除元素节点

    • parentNode.removeChild("child");
  • 复制元素节点

    • node.cloneNode();

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


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

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


(3)三种动态创建元素方法的区别

document.writeelement.innerHTMLdocument.createElement()

  • 关于document.write()

    • document.write是直接将内容写入页面的内容流,
    • 如果是在文档流执行完毕后,执行 document.write,则会导致页面内容全部重绘
  • 关于element.innerHTML

    • 创建多个元素的效率高,但结构稍微复杂
    • 但通过拼接字符串的方法添加元素到页面中效率很低(字符串的不可变性)
    • 因此,可以通过**数组的方法push()**添加元素,效率最高
  • 关于document.createElement()

    • 创建多个元素的效率低,但结构更清晰
    • 通过appenChild()直接追加子元素到父元素末尾,效率高

02.关于页面元素的【事件】

(1)基本概念

  • 基本事件组成

    • 事件三要素:
      • 事件源:被触发事件的对象
      • 事件类型:如何触发事件,如:点击、滑过、键盘输入等
      • 事件处理程序:完成什么事件
    • 关于this
      • this指向的是事件函数调用者
  • 基本事件执行过程

//1. 首先获取事件源元素
var btn = document.getElementById("btn")
//2. 然后 绑定事件(注册事件)
//3. 最后添加事件处理程序
div.onclick = function(){
    alert("触发事件")
}


(2)元素注册事件的两种方式

  • 传统注册方式

    • 利用on开头的事件,如:onclick
    • 唯一性:同一个元素的同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数
  • addEventListener事件监听

    • 语法结构:eventTarget.addEventListener(type, listener, useCapture);
      • 将指定的监听器注册到eventTarget(目标对象)上

      • type:事件类型字符串,如clickmousemover

      • listener:事件处理函数,事件发生时,会调用该监听函数

      • useCapture:可选参数,是一个布尔值,默认false

  • 注册事件

eventTarget.addEventListener("type", function)
//为目标函数绑定 type 事件,该事件的处理函数是 function


(3)删除事件的方式

  • 传统方式删除事件

    • eventTarget.onclick = null
  • removeEventListener删除事件

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

(4)DOM事件流

  • 基本概念

    • 事件流是指:从页面中接收事件的顺序
      • 事件发生时,会在元素节点之间,按照特定的顺序传播,这个传播过程即DOM事件流
  • 阶段概述

    • 捕获阶段

      • 从 DOM 最顶层的节点开始,然后逐级向下传播,到目标元素接收的过程

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

    • 当前目标阶段

    • 冒泡阶段

      • 事件开始时,从目标事件元素开始接收,然后逐级向上传播,到DOM最顶层的节点,这一过程

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

  • 其它需要注意

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

(5)事件对象

  • 基本概念
    • 事件发生后,跟事件相关的一系列信息数据集合,都会存放在一个事件对象event里面

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

      eventTarget.onclick = function(event){ ... }
      

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

    • 事件对象的兼容性问题

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

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

(6)事件对象的常用属性和方法

  • 返回触发事件的对象:谁触发的事件,就返回谁,语法:e.target

  • 返回的是绑定事件的对象:谁绑定的事件,就返回谁,语法:this

  • 返回触发事件的类型:用什么方式触发,就返回什么类型,语法:e.type

  • 阻止默认事件

    • 高版本:e.preventDefault()

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

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

    • 标准写法:e.stopPropagation()

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

      if(e && e.stopPropagation){
          e.stopPropagation()
      }else{
          window.event.cancelBubble = true
      }
      
      

(7)事件委托(代理、委派)

  • 不需要给每个子节点单独设置事件监听器,而是把事件监听器设置再其父节点上,即把事件委托给了父节点

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


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


03.鼠标事件

(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)
    })
    
    

04.键盘事件

(1)基本事件

  • keyup :按键弹起的时候触发 ,松开键盘时只触发一次

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

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

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

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

(2) 键盘事件对象

  • e.keycode:返回对应按键的ASCII码值

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

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

    • keypress可以区分字母大小写


本人前端小菜鸡,如有不对请谅解