跳至主要內容

DOM

zfh大约 10 分钟约 2897 字...

DOM(文档对象模型)是指浏览器将HTML文档解析成一颗树状结构,通过该结构可以操作文档中的元素和内容

nodeType

节点的 nodeType 属性可以显示这个节点具体的类型

nodeType值节点类型
1元素节点,例如p div
3文字节点
8注释节点
9document节点
10DTD节点

节点访问

getElementById()

注意

通过 ID 获取元素的上下文只能是 documentgetElementById 只在 Document 类的原型上,HTMLDivElement 没有继承 Document 类,所以div不能使用 getElementById 方法

document.getElementById()功能是通过id得到元素节点

  • 如果页面上有相同id的元素,则只能得到第一个(一个页面一个 id 命名一般只能出现一次)
  • 括号里面不要写#

getElementsByTagName() 不常用

getElementsByTagName()方法的功能是通过标签名得到节点数组

  • 数组方便遍历,从而可以批量操控元素节点
  • 即使页面上只有一个指定标签名的节点,也将得到长度为 1 的数组
  • 上下文可以是 document,也可以是一个元素

getElementsByClassName()

getElementsByClassName()方法的功能是通过类名得到节点数组

  • 即使页面上只有一个指定类名的节点,也将得到长度为 1 的数组
  • 括号内不要写"."
  • 上下文可以是 document,也可以是一个元素

querySelector()

querySelector()方法的功能是通过选择器得到元素

  • querySelector()方法只能得到页面上一个元素,如果有多个元素符合条件,则只能得到第一个元素

  • 上下文可以是 document,也可以是一个元素

querySelectorAll()

querySelectorAll()方法的功能是通过选择器得到元素数组

  • 即使页面上只有一个符合选择器的节点,也将得到长度为 1 的数组

  • 上下文可以是document,也可以是一个元素

节点关系

注意

  • DOM 中,文本节点也属于节点,在使用节点的关系时一定要注意

  • 在标准的 W3C 规范中,空白文本节点也应该算作节点,但是在 IE8 及以前的浏览器中会有一定的兼容问题,它们不把空文本节点当做节点

关系考虑所有节点只考虑元素节点
子节点childNodeschildren
父节点parentNode
第一个子节点firstChildfirstElementChild
最后一个子节点lastChildlastElementChild
前一个兄弟节点previousSiblingpreviousElementSibling
后一个兄弟节点nextSiblingnextElementSibling

节点操作

改变内容

改变元素节点中的内容可以使用两个相关属性

  • innerHTML 属性能以HTML 语法设置节点中的内容
  • innerText 属性只能以纯文本的形式设置节点中的内容

改变样式

box.style.backgroudColor = 'red'

改变属性

标准 W3C 属性,如 srchref 等等,只需要直接打点进行更改即可

oImg.src = 'images/2.png'

class 属性需要通过 className 属性 获取和修改,而不是class,修改该值将直接覆盖之前所有的类名

classList 属性返回元素的类名,该属性用于在元素中添加,移除及切换 CSS 类,classList 属性是只读的,但你可以使用 add()remove() 方法修改它:

document.getElementById('myDIV').classList.add('mystyle')

不符合 W3C 标准的属性,要使用 setAttribute() getAttribute()来设置、读取

oBox.setAttribute('number', 10)
var n = oBox.getAttribute('number')
alert(n) //10

自定义属性

在 HTML5 中添加了 data-的方式来自定义属性,所谓 data-实际上就是 data-前缀加上自定义的属性名,使用这样的结构可以进行数据存放。使用 data-可以解决自定义属性混乱无管理 的现状

  1. 设置自定义属性的 2 种方式:

(1)第一种方式是可以直接在 HTML 标签上面书写:

<h2 data-weather="rain">今天下雨啦</h2>

上面 data-weather 就是一个自定义属性,值为 rain

注意:如果设置的自定义属性是多个单词的组合的话,需要用中横线(-)链接,比如:

<h2 data-birth-date="20201128">今天下雨啦</h2>

(2)第二种方式是通过 js dataset 属性来设置:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <h2>今天下雨啦</h2>
    <script>
      var h2 = document.querySelector('h2')
      h2.dataset.weather = 'rain'
    </script>
  </body>
</html>

这样也是设置了一个 data-weater 的自定义属性,值为 rainHTML5 中元素都会有一个 dataset 的属性

注意:如果设置的是多个单词的组合的话,需要使用驼峰命名法来书写,如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <h2>今天下雨啦</h2>
    <script>
      var h2 = document.querySelector('h2')
      h2.dataset.birthDate = '20201128'
    </script>
  </body>
</html>
  1. js 读取自定义属性

读取的时候通过 dataset 属性来获取自定义属性,需要去掉 data- 前缀,连字符需要转化为驼峰命名,如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <h2 data-weather="rain" data-birth-date="20201128">今天下雨啦</h2>
    <script>
      var h2 = document.querySelector('h2')
      console.log(h2.dataset.weather) // rain
      console.log(h2.dataset.birthDate) // 20201128
    </script>
  </body>
</html>
  1. CSS 也可以通过自定义属性来书写样式,如下:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style>
      h2[data-birth-date='20201128'] {
        color: red;
      }
    </style>
  </head>
  <body>
    <h2 data-birth-date="20201128">今天下雨啦</h2>
  </body>
</html>
  1. 自定义属性 demo

当然也可以使用 setAttribute()和 getAttribute()来设置、读取

See the Pen by zhangfanhang on CodePen.

创建节点

document.createElement()方法用于创建一个指定 tagName HTML 元素

var oDiv = document.createElement('div')

新创建出的节点并没有被挂载到 DOM 树上,必须继续使用 appendChild() insertBefore() 方法将新创建的节点插入到 DOM 树上

document.createDocumentFragment()用于创建文档片段,将元素附加到文档片段,然后将文档片段附加到 DOM 树。在DOM树中,文档片段被其所有的子元素所代替。

因为文档片段存在于内存中,并不在DOM 树中,所以将子元素插入到文档片段时不会引起页面回流open in new window(对元素位置和几何上的计算)。因此,使用文档片段通常会带来更好的性能。

      const list = document.querySelector('.list')
      // 文档切片
      const frag = document.createDocumentFragment()
      for (let i = 0; i < 10000; i++) {
        const title = document.createElement('h1')
        title.innerText = `list item ${i}`
        frag.appendChild(title)
      }
      list.appendChild(frag)

appendChild()

任何已经在DOM 树上的节点,都可以调用 appendChild(),它可以将新节点挂载到它的内部,成为它的最后一个节点

父节点.appendChild(新节点)

insertBefore()

任何已经在 DOM 树上的节点,都可以调用insertBefore() 方法,它可以将孤儿节点挂载到它的内部,成为它的某个子节点之前的节点

父节点.insertBefore(新节点, 父节点的某个子节点)

移动节点

如果将已经挂载到 DOM 树上的节点成为 appendChild()或者 insertBefore()的参数,这个节点将会被移动

新父节点.appendChild(已经有父亲的节点)

新父节点.insertBefore(已经有父亲的节点, 新父节点的某个子节点)

删除节点

  • removeChild()方法从 DOM 中删除一个子节点
  • 节点不能主动删除自己,必须由父节点删除它

克隆节点

  • cloneNode()方法可以克隆节点
var newNode = 老节点.cloneNode()

var newNode = 老节点.cloneNode(true)
  • 参数是一个布尔值,表示是否采用深度克隆:如果为 true,则该节点的所有后代节点也都会被克隆,如果为 false,则只克隆该节点本身

DOM 事件

事件监听

常见的鼠标事件监听

事件名事件描述
onclick当鼠标单击某个对象
ondbclick当鼠标双击某个对象
onmousedown当某个鼠标按键在某个对象上被按下
onmouseup当某个鼠标按键在某个对象上被松开
onmousemove当某个鼠标按键在某个对象上被移动
onmouseenter当鼠标进入某个对象(相似事件onmouseover)
onmouseleave当鼠标离开某个对象(相似事件onmouseout)

常见的键盘事件监听

事件名事件描述
onkeypress当某个键盘的键被按下(系统按钮无法得到识别)
onkeydown当某个键盘的键被按下(系统按钮可以识别,并且会先于onkeypress发生)
onkeyup当某个键盘的键被松开

事件传播

当盒子嵌套时事件监听的执行顺序事件的传播是:先从外到内(捕获阶段),然后再从内到外(冒泡)

on只监听冒泡阶段

addEventListener()当第三个参数为false时,事件处理程序将在事件冒泡阶段执行。如果不传递第三个参数,默认为false,即在事件冒泡阶段执行。

      d.addEventListener('click',()=>{
		// true 监听捕获阶段 
		// false,不设置 监听冒泡阶段
      },true)

事件对象

  • 事件处理函数提供一个形式参数,它是一个对象,封裝了本次事件的细节
  • 这个参数通常用单词 event 或字母 e 表示

鼠标位置

属性属性描述
clientX鼠标指针相对于浏览器的水平坐标
clientY鼠标指针相对于浏览器的垂直坐标
pageX鼠标指针相对于整张网页的水平坐标
pageY鼠标指针相对于整张网页的垂直坐标
offsetX鼠标指针相对于事件源元素的水平坐标
offsetY鼠标指针相对于事件源元素的垂直坐标

当鼠标移入黑色区域便会显示该位置的坐标(相对于事件源元素)

See the Pen by zhangfanhang on CodePen.

e.charCode 和 e.keyCode 属性

e.charCode 属性通常用于 onkeypress 事件中,表示用户输入的字符的“字符码”

e.keyCode 属性通常用于 onkeydown 事件和 onkeyup 中,表示用户按下的按键的“键码“

按方向键可以控制页面上的盒子移动

See the Pen by zhangfanhang on CodePen.

e.preventDefault()方法

  • e.preventDefault()方法用来阻止事件产生的”默认动作“

  • 一些特殊的业务需求,需要阻止事件的“默认动作”

制作一个文本框,只能让用户在其中输入小写字母和数字,其他字符输入没有效果

See the Pen by zhangfanhang on CodePen.

e.stopPropagation()方法

用来阻止事件继续传播

制作一个弹出层:点击按钮显示弹出层,点击网页任意地方,弹出层关闭

See the Pen by zhangfanhang on CodePen.

事件委托(代理)

提示

e.target指向的是触发事件的元素

e.currentTarget指向的是添加监听事件的元素

利用事件冒泡机制,将后代元素事件委托给祖先元素

动态绑定事件

See the Pen by zhangfanhang on CodePen.

事件委托的使用场景

  • 当有大量类似元素需要批量添加事件监听时,使用事件委托可以减少内存开销

  • 当有动态元素节点上树时,使用事件委托可以让新上树的元素具有事件监听

定时器和延时器

定时器

  • setInterval()函数可以重复调用一个函数,在每次调用之间具有固定的时间间隔

  • setInterval()函数可以接收第 3、4…个参数,它们将按顺序传入函数

  • ClearInterval()函数可以清除一个定时器,需要传入定义器的变量

延时器

  • setTimeout()函数可以设置一个延时器,当指定时间到了之后,会执行函数一次,不再重复执行

  • clearTimeout()函数可以清除延时器

上次编辑于:
本站勉强运行 小时
本站总访问量
網站計數器