javascript DOM、事件、事件流、节点操作、元素属性(笔记)

文章目录

      • 1. 认识DOM
      • 2. 获取元素
        • 2.1 通过标签名获取
        • 2.2 通过ID获取
        • 2.3 通过类名获取
        • 2.4 H5新增的获取方式
        • 2.5 特殊元素的获取
      • 3. 事件
        • 3.1 事件三要素
        • 3.2 事件类型
        • 3.3 注册事件
        • 3.4 派发事件
        • 3.5 删除事件
        • 3.6 事件流
        • 3.7 鼠标事件对象
        • 3.8 键盘事件对象
        • 3.9 触摸事件对象
        • 3.10 事件委托(事件代理)
      • 4. 元素自定义属性
        • 4.1 默认的自定义属性
        • 4.2 h5新增的自定义属性
      • 5. 节点操作
        • 5.1 节点类型
        • 5.2 节点自身的信息
        • 5.3 获取父元素
        • 5.4 获取子元素
        • 5.5 获取兄弟元素
        • 5.6 添加节点对象
        • 5.7 删除节点
        • 5.8 克隆节点
        • 5.9 替换节点
        • 5.10 移动节点
      • 6. 获取元素属性
        • 6.1 偏移量 offset
        • 6.2 offset 与 style 区别
          • 6.2.1 offset
          • 6.2.2 style
        • 6.3 元素可视区 client
        • 6.4 元素滚动 scroll
      • 7. 操作css
        • 7.1 类名与ID
        • 7.2 行内样式
        • 7.3 全部样式

1. 认识DOM

文档对象模型(Document Object Model)

  • 文档:一个页面就是一个文档,DOM中使用document表示
  • 节点:页面中的所有内容,在文档树中都是节点(标签、属性、文本、注释等),使用node表示
  • 标签节点:网页中所有的标签,通常称为元素节点,有简称为"元素",使用element表示

2. 获取元素

2.1 通过标签名获取

// get方式获取一组元素的都是伪数组
// 返回HTMLCollection,它是即时更新的,当其所包含的文档结构发生改变时,它会自动更新。
let lis = document.getElementsByTagName(tag)

2.2 通过ID获取

// 选择第一个匹配的元素
let div = document.getElementById(id)

2.3 通过类名获取

// 也是实时更新
let lis = document.getElementsByClassName(class)

2.4 H5新增的获取方式

// 选择第一个匹配的元素(css怎么获取它就怎么获取)
let div = document.querySelector(css选择器)

// 选择一组元素(类数组)
// 返回NodeList(静态的不会实时更新),它是H5以后新增的可以使用forEach去遍历
// 通过这种方式获取的才是静态的,但是通过实时更新的父元素点出来的孩子们,即使是NodeList也是实时的
let div = document.querySelectorAll(css选择器)

2.5 特殊元素的获取

// 获取html 文档对象
document.documentElement

// 获取body标签
document.body

3. 事件

3.1 事件三要素

  • 事件源(谁要触发事件):触发事件的元素
  • 事件类型(触发什么事件):例如 click 点击事件
  • 事件处理程序(触发对应事件后要干什么):触发事件后执行的函数

3.2 事件类型

  • 鼠标事件

    // 1.鼠标左键按下(点击事件)
    btn.onclick = function(){}
    
    // 2.鼠标右键点击(在右键菜单显示前触发)
    contextmenu
    
    // 3.鼠标双击事件
    dblclick
    
    // 4.鼠标按下事件
    mousedown
    
    // 5.鼠标抬起事件
    mouseup
    
    // 6.鼠标移入事件
    mouseover
    
    // 7.鼠标移入事件(不冒泡,目标元素不冒给自己,其他元素的相同事件不会触发自己)
    mouseenter
    
    // 8.鼠标移动触发
    mousemove
    
    // 9.鼠标移出事件
    mouseout
    
    // 10.鼠标移出事件(不冒泡)
    mouseleave
    
    // 11.在鼠标上触发任意按钮触发
    mouseup
    
    // 12.鼠标滚轮事件
    wheel
    
    // 15.文档视图或者一个元素在滚动时触发,鼠标键盘都可以
    scroll
    
  • 表单事件

    // 1.元素获得焦点
    focus
    
    // 2.元素失去焦点
    blur
    
    // 3.输入事件(每次输入都会触发)
    input
    
    // 4.当用户更改表单,并提交时触发
    change
    
    // 5.剪切
    cut
    
    // 6.拷贝
    copy
    
    // 7.粘贴
    paste
    
  • 键盘事件

    // 键盘按下,keyCode不区分字母大小写
    keydown
    
    // 键盘按下(它不识别功能键 ctrl,shift等)
    keypress
    
    // 键盘抬起
    keyup
    
    // 三个事件的执行顺序
    keydown -- keypress -- keyup
    
  • 移动端事件

    // 手指触摸到一个DOM元素时触发(按下)
    touchstart
    
    // 手指在一个DOM元素上滑动时触发
    touchmove
    
    // 手指从一个DOM元素上移开时触发(抬起)
    touchend
    
  • 全局事件

    // document开头的事件
    

3.3 注册事件

  • 传统注册方式

    • 利用 on 开头的事件 onclick
    • 注册事件具有唯一性
    • 同一个元素设置重复的事件,只会执行最后面的事件
  • 监听注册方式

    • w3c 标准推荐方式

    • addEventListener() 它是一个方法,不需要加 on

    • IE9 之前的IE不支持此方法,可以使用attachEvent() 代替,需要加 on

    • 同一个元素可以注册多个监听器,按注册顺序依次执行

      element.addEventListener("click",funcion,事件流)
      

3.4 派发事件

  • EventTarget.dispatchEvent(event):手动去派发事件
  • 可以派发自定义事件,也可以派发原有事件(原有事件还可以正常使用)
  • 必须要传入一个事件对象,可以通过 new Event(事件类型),创造一个自定义事件

3.5 删除事件

  • 传统方式:element.onclick = null

  • 监听方式:element.removeEventListener(“click”,function)

    兼容性的删除方式:detachEvent(“onclick”,function)

    这里的function必须和添加事件的function是同一个

3.6 事件流

  • 在触发事件时会经历三个阶段

注意,事件流是元素父子关系(元素嵌套关系),而不是层叠关系

  1. 捕获阶段:document—Element html—Element body—Element div
  2. 目标对象:Element div
  3. 冒泡阶段:Element div—Element body—Element html—document
  4. 注意:捕获阶段不会触发事件,获取到目标对象后向上冒泡,才会触发父元素的事件
  • 默认事件为冒泡事件(从内向外)

    // addEventListener 一共有三个参数
    element.addEventListener("click",funcion,事件流)
    
    // 事件流,默认为false,为事件冒泡(先执行自己的,在执行父元素的)
    // 如果为true,那么就为事件捕获(先执行父元素的,在执行自己的)
    

3.7 鼠标事件对象

在使用事件方法时,可以传入一个参数event(事件对象)

  1. event.type:返回事件类型
  2. event.target:返回目标对象
  3. event.currentTarget:返回注册事件的对象,不一定是目标事件,可能是冒泡的,等同于this
  4. event.preventDefault():阻止默认事件,比如a元素的跳转
  5. event.stopPropagation():阻止事件冒泡(都是给目标对象添加)

this与event.target的区别:this是函数调用者,event.target是目标对象(比如给ul添加事件使用this改变样式的话,只能改变ul的样式,用target的话点哪个li就只改变哪个li)

鼠标事件属性 说明
event.clientX 返回鼠标相对于浏览器窗口,可视区域的 X 坐标( 浏览器窗口 )
event.clientY 返回鼠标相对于浏览器窗口,可视区域的 Y 坐标
event.pageX 返回鼠标相对于文档页面 X 坐标,IE9+支持( 文档内容 )
event.pageY 返回鼠标相对于文档页面 Y 坐标,IE9+支持
event.screenX 返回鼠标相对于电脑屏幕的 X 坐标( 电脑屏幕 )
event.screenY 返回鼠标相对于电脑屏幕的 Y 坐标

3.8 键盘事件对象

  • keydown不区分大小写,keypress区分大小写( keyCode:编码 )
  • 也可以通过 key 去判断按的什么键( key:字符串 )

3.9 触摸事件对象

触摸列表 说明
touches 正在触摸屏幕的所有手指的一个列表
targetTouches 正在触摸当前DOM元素上的手指的一个列表
changedTouches 手指状态发生了改变的列表,从无到有,从有到无变化

3.10 事件委托(事件代理)

事件委托是利用了事件冒泡的特征

还拿ul举例子,比如我想给ul下面很多个li标签添加事件,可以只给ul添加事件,就相当于利用冒泡的特性给每一个li都加了事件(这里要注意,目标对象的事件不一定是自己的事件,也可以是父元素给委托的事件)

4. 元素自定义属性

4.1 默认的自定义属性

// 获取标签结构中的自定义属性值,也可以获取标签自身的属性值
element.getAttribute("自定义属性名")

// 为标签添加(修改)自定义的属性名和属性值,有就修改,没有就添加
element.setAttribute("自定义属性名", "自定义属性值")

// 删除标签中的自定义属性
element.removeAttribute("自定义属性名")

4.2 h5新增的自定义属性

// 注意:设置的时候必须以 data-xxx的格式
// 所有以data-开头的属性都可以使用dataset去增删改查
// 获取
element.dataset.xxx

// 修改(添加)
element.dataset.xxx = value

// 删除
delete element.dataset.xxx

5. 节点操作

5.1 节点类型

  • 元素节点,nodeType 为1
  • 属性节点,nodeType 为2
  • 文本节点,nodeType 为3

5.2 节点自身的信息

  • nodeType:当前节点类型
  • nodeValue:节点文本内容
  • nodeName:ele节点标签,会返回大写的

5.3 获取父元素

  • parentElement:父元素
  • parentNode:父元素节点

5.4 获取子元素

  • children:子元素(元素)
  • childNodes:子元素节点(包括元素、属性、文本、注释等)
  • firstChild:获取第一个子元素节点
  • firstElementChild:获取第一个子元素
  • lastChild:获取最后一个子元素节点
  • lastElementChild:获取最后一个子元素

5.5 获取兄弟元素

  • nextSibling:获取下一个兄弟节点
  • previousSibling:获取上一个兄弟节点
  • nextElementSibling:获取下一个兄弟元素(H5新增)
  • previousElementSibling:获取上一个兄弟元素(H5新增)

5.6 添加节点对象

  • 创建(三种方式)

    // 创建节点对象(这个时候还没上树)
    document.createELement("标签名")
    
    // 创建文档片段,会创建一个空白的文档,可以用来装载元素
    document.createDocumentFragment()
    
    // 会覆盖node中原有的内容
    // innerText和innerHTML差不多,只是innerText不能识别标签
    // textContent和outerHTML和上面两个都是差不多的,textContent兼容性好一些
    node.innerHTML = 标签内容
    
    // 对整个页面进行重绘
    document.write(标签内容)
    
  • 追加

    // 追加节点对象(上树)
    parentNode.append("元素对象或字符串") // 如果是字符串就是添加文本节点
    parentNode.appendChild("元素对象") // 只能是元素对象
    parentNode.prepend() // 和 append 一样不过是添加到最前面
    
  • 插入

    // 第一种
    // 插入指定元素之前(上树)
    parentNode.insertBefore(ele,指定元素)
    
    // 第二种
    // 这个方法不会覆盖之前的html内容
    // position,有四个参数
    	// 'beforebegin':元素自身的前面。
    	// 'afterbegin':插入元素内部的第一个子节点之前。
    	// 'beforeend':插入元素内部的最后一个子节点之后。
    	// 'afterend':元素自身的后面。
    // text:要插入的HTML元素
    
    // 这三个的插入方法都是差不多的
    // 使用 insertAdjacentHTML 插入用户输入的HTML内容的时候,需要转义之后才能使用
    element.insertAdjacentHTML(position, text);
    // 插入的元素
    element.insertAdjacentElement(position, element);
    // 插入的文本
    element.insertAdjacentText(position, text);
    
    
    
    
    <p>
      
      foo
      
    p>
    
    
    // 第三种(还在实验中)
    // 插入当前目标元素之前或之后
    element.before("元素对象或字符串")
    element.after("元素对象或字符串")
    

5.7 删除节点

  • parentNode.removechild(“指定元素”):返回被删除的节点
  • node.remove():删除当前元素,不会返回

5.8 克隆节点

// 当为true时为深层克隆,克隆当前节点和子节点,并返回克隆的节点
node.cloneNode(true)

// 当为false时为浅层克隆,只克隆当前节点(标签、属性和类名)
node.cloneNode(false)

5.9 替换节点

Node.replaceChild(newChild, oldChild)

5.10 移动节点

// externalNode:需要提取的节点
// 然后把 node 插入到新的位置
node = document.adoptNode(externalNode);

6. 获取元素属性

6.1 偏移量 offset

offset 翻译过来就是偏移量, 我们使用 offset系列相关属性可以动态的得到该元素的位置( 偏移 )、大小等。

  1. 获得元素距离带有定位父元素的位置
  2. 获得元素自身的大小(宽度高度)
  3. 注意:返回的数值都不带单位
offset系列属性 作用
ele.offsetParent 返回具有定位元素的父级元素,如果上层一直没有则返回body
ele.offsetTop 返回元素相对带有定位父元素上方的偏移,子border到父border
ele.offsetLeft 返回元素相对带有定位父元素左方的偏移,如果没有就是body
ele.offsetWidth 返回自身content+padding+border的宽度,返回值不带单位
ele.offsetHeight 返回自身content+padding+border的高度,返回值不带单位

6.2 offset 与 style 区别

6.2.1 offset
  • offset 可以得到任意样式表中的样式值
  • offset 系列获得的数值是没有单位的
  • offsetWidth 包含padding+border+width
  • offsetWidth 等属性是只读属性,只能获取不能赋值
  • 所以,我们想要获取元素大小位置,用offset更合适
6.2.2 style
  • style 只能得到行内样式表中的样式值
  • style.width 获得的是带有单位的字符串
  • style.width 获得不包含padding和border 的值
  • style.width 是可读写属性,可以获取也可以赋值
  • 所以,我们想要给元素更改值,则需要用style改变

6.3 元素可视区 client

client 翻译过来就是客户端,我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client 系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

client系列属性 作用
ele.clientTop 返回该元素上边框的大小
ele.clientLeft 返回该元素左边框的大小
ele.clientWidth 返回自身content+padding的宽度,返回值不带单位
ele.clientHeight 返回自身content+padding的宽度,返回值不带单位

6.4 元素滚动 scroll

scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。

scroll系列属性 作用
ele.scrollTop 返回自身被卷去上侧的距离
ele.scrollLeft 返回自身被卷去左侧的距离
ele.scrollWidth 返回自身content的宽度
ele.scrollHeight 返回自身content的高度

ele.scrollTo(x,y),手动滚动dom元素

7. 操作css

7.1 类名与ID

// 像类名与ID直接元素点就可以使用,一般其他的样式要style点才可以
// 类名
className // 返回类名,可读可写
classList // 将属性作为列表来返回
/*
 classList 可以使用
   add(class):添加类名
   remove(class):删除类名
   toggle(class):切换类名,如果有类名删除没有就添加
   contains(class):判断是否存在类名,返回布尔值
*/

// ID
id // 返回id,可读可写

7.2 行内样式

// 1. 通过属性修改
// 上面说到 DOM 提供的有很多获取元素宽高等一些属性
// 但是 style 可以获取行内样式,也可以添加行内样式
// background-color:像这种样式需要转为大驼峰
element.style.backgroundColor = "red" // 可读可写

// 2. 通过 API 修改
/*
  propertyName:需要添加或修改的属性,有则修改无则添加,和 css 一样写法
  value(可选):需要修改或填的属性值,如果不填为空
  priority(可选):设置 css 优先级 "important"

  css 变量通过 js 去设置,需要使用这种方式,直接 style 点不行
*/
element.style.setProperty(propertyName, [value], [priority]);

7.3 全部样式

<div class="box">div>

<script>
  // 获取box元素
  let box = document.querySelector(".box")
  // 获取box的全部样式(计算后的样式)
  let boxStyle = window.getComputedStyle(box)
  // 获取box伪元素的全部样式
  let afterStyle = window.getComputedStyle(box, "::after")
  // 这种方式是只读的
script>

你可能感兴趣的:(JS,javascript,前端,html,dom操作,dom)