DOM简介

啥是DOM?

  • The Document Object Model
  • JS可修改和查询HTML文档
  • Accessible via the JS global scope, aliases:
    • window
      • 批注: console.log(window) // 返回window对象
    • this (When not using 'use strict';)
      • 批注:console.log(this) // 返回window对象
      • 批注:'use strict'; (严格模式)
      • 批注:this的指向
        • 全局作用域或者普通函数中的this指向window
          • e.g. setInterval中的this指向window
          • e.g. 全局变量this指向window
        • 构造函数中,this指向构造函数的实例
          e.g. function Fun() {console.log(this); // this 指向的是fun 实例对象 }
        • 方法调用时,谁调用this指向谁
            sayHi: function() {
                console.log(`o:`+this); // this指向的是 o 这个对象
            }
        }

DOM hierarchy(层次结构)

  • Rooted at window.document (html tag) 批注:返回 #document 文档对象(<!DOCTYPE html> <html>...</html>)

    • 批注: 使用时可省略window,直接写document
  • Follows HTML document structure

    • window.document.head 批注: // 返回 <head>...</head>
    • window.document.body 批注: // 返回<body>...</body>
      • 批注:document.documentElement 返回 <html>...</html>
  • Tree nodes (DOM objects) have tons(~250) of properties, most private

    • Objects(representing elements, raw, text, etc.) have a common set of properties and methods called a DOM “Node”
      • 批注:节点包含nodeType, nodeName, nodeValue 三个基本属性
      • 批注:元素节点的nodeType = 1,属性节点的nodeType = 2,文本节点的nodeType = 3

DOM Node properties and methods

  • Identification
    • nodeName property is element type
      • 批注:返回节点名称。元素节点返回标签名,文本节点返回#text字符串。只读属性。
  • Encode(编码) document’s hierachical structure
    • parentNode, nextSibling, previousSibling, firstChild, lastChild
      • 批注:
        1. parentNode返回最近的父级,找不到父级则返回 null
          1. offsetParent 返回定位过的父级,否则返回body
        2. nextSibling返回下一个兄弟节点(非下一个元素节点)
          • 下一个元素节点: nextElementSibling
        3. previousSibling返回上一个兄弟节点
          • 上一个元素节点:previousElementSibling
        4. firstChild返回第一个子级节点(注意:不是返回第一个元素节点)。
          • 想要返回第一个元素子节点,请用firstElementChild或者children[0],前者IE9以上支持,后者无兼容性问题。
        5. lastChild返回最后一个子级节点(注意:不是返回第一个元素节点)
          • 返回最后一个元素节点请用:lastElementChild(IE9以上支持)或者`children[parentNode.children.length - 1]
        6. 补充:
          • parentNode.children 返回所有的元素子节点,将之存放在数组中
  • Provide accessor and mutator methods(访问和修改)
    • E.g. getAttribute, setAttribute methods, etc.

访问DOM 节点

  • 遍历DOM层级(不推荐)
    • element = document.body.firstChild.nextSibling.firstChild;
    • element.setAttribute(...
  • 使用DOM查找方法
    • HTML: <div id = "div42">...</div>
    • element = document.getElementById("div42");
    • element.setAttribute(...
      • 批注:直接查找DOM节点的方法:
        • document.getElementById
        • document.querySelector
        • 以上直接返回元素对象
  • 查找多个DOM节点
    • 通过getElementsByClassName(), getElementsByTagName(),...
      • 能从头查找任何元素
        • document.body.firstChild.getElementsByTagName()
          • 批注:查找多个DOM节点的方法:
            • getElementsByClassName()
            • getElementsByTagName()
            • document.querySelectorAll()
            • getElementsByClassName()getElementsByTagName()返回对象集合,以伪数组的形式存储,如果找不到符合要求的元素,返回空的伪数组
            • document.querySelectorAll()返回节点列表,找不到符合要求的元素,返回空的节点列表
            • 要访问其中所有元素,可遍历数组或者列表。如果访问其中一个元素,arr[index]

更常用的节点属性/方法

  • textContent - 节点及其后代的文本内容
    • 批注:包含空格和换行,包括隐藏元素,防止XSS攻击
  • innerHTML - HTML syntax describing the element’s descendants(描述元素后代)
    • <p>Sample<b>bold</b>display</p>
    • p.innerHTML 返回 Sample<b>bold</b>display
  • outerHML - 和innerHTML类似,但是包含元素本身
    • <p>Sample<b>bold</b>display</p>
    • p.outerHTML 返回 <p>Sample<b>bold</b>display</p>
  • getAttribute() / setAttribute() - 获取元素、设置元素属性
    • 批注:
      1. 获取属性值
        1. 写法:element.getAttribute('id')
      2. 自定义属性
        1. 写法:element.setAttribute('attribute','value') (常用)
        2. H5新增的获取自定义属性的方法:
          1. 添加自定义属性:element.setAtribute('data-attribute', 'value')
            1. data-开头的自定义属性被存放在dataset中
          2. 获取自定义属性:
            1. element.dataset(返回自定义属性集合)
            2. 获取其中一个自定义属性:
            1. element.dataset.attribute
            2. element.dataset['attribute']
      3. 修改元素属性值:
        1. 写法:element.attribute = 'value'
      4. 移除属性
        1. 写法:element.removeAttribute(属性)

常见的DOM mutating operations (修改操作)

  • 改变元素内容
    • element.innerHTML = "this text is <i>important</i>" ;
    • 替换内容,保留属性。DOM节点structure (结构)被更新
  • 改变标签的属性:
    • img.src = 'newImage.jpg';
  • 使元素可见或者不可见:
    • 不可见: element.style.display = 'none';
    • 可见: element.style.displya = 'block';

DOM和CSS交互

  • 更新元素的class属性
    • element.className = 'new';
      • 批注:会替换原先类名
        • 如果想添加class值,可使用element.classList
          • classList 只读属性,返回DOMTokenList
          • 可以使用add(), remove(), replace(), toggle()方法修改其DOMTokenList的值。
            - add(cls1, cls2, cls3) 添加类
            • remove(cls,cls1) 移除类
            • replace(cls,cls2) cls替换为cls2
            • toggle(cls) 如果cls已存在,则移除,不存在则添加
            • 可使用展开语法添加/移除多个类值
              • const cls = ['foo', 'bar']
              • div.classList.add(...cls);
              • div.classList.remove(...cls);
  • 更新元素的样式
    • element.style.color = '#000' // 不是首选方式
  • 通过CSS选择器查询DOM
    • document.querySelector()element.querySelectorAll()

更改节点结构

  • 创建新元素
    • element = document.createElement('p'); 或者 element = document.createTextNode('My text');
    • 也可通过cloneNode()克隆已经存在的节点
      • 批注:
        • cloneNode(true) 深拷贝- 复制标签以及里面的内容
        • cloneNode(false) 浅拷贝 - 复制标签,不复制里面的内容(默认值)
  • 将创建的节点添加到已有的节点中
    • parent.appendChild(element); 或者 parent.insertBefore(element, sibling);
      • 批注:
        • appendChild(element) 将元素插入到父级末尾
        • parent.insertBefore(element, sibling) 将元素插入到指定的兄弟节点前面
  • 移除节点:
    • node.removeChild(child);
      • 批注:返回被删除的子节点,上面写法不会保留对child的引用,短时间内会被内存管理回收。如果写为let oldChild = node.removeChild(child) 则会保留对child的引用。
  • 虽然但是,用innerHTML 做这些修改更简单效率也更高
    • 以数组而不是以字符串拼接的方式

其他DOM操作

  • 重定向到一个新页面:
    • window.location.href = "newPage.html";
    • 注意:可能导致JS脚本执行终止
    • 批注:location其他常见的方法
      • location.assign(url) - 记录浏览历史,可以回退
      • location.replace(url) - 不记录浏览历史,不可回退
      • location.reload() - 强制刷新
      • location.search - 获取url中的键值对(位于端口后面,?起头)
    • 批注:history相关的方法
      • history.forward() - 前进一页
      • history.backward() - 后退一页
      • history.go(1) - 前进一页
      • history.go(-1) - 后退一页
  • 和用户交流(communicating with the user)
    • console.log("Read point A"); // message to browser log
    • alert("wow!"); confirm("ok?") // 弹出对话框
    • 批注: window.confirm(message)
      • message 对话框中的可编辑字符串
      • result 是布尔值,表示选择确定还是取消(true表示ok)

DOM坐标系

  • 屏幕原点在左上方,垂直方向下降,y值增加(y increase as you go down)
  • 元素的位置由其左上角坐标决定
  • element.offsetLeftelement.offsetTop 读取位置
  • 坐标相对于element.offsetParent, 而其并不完全等价于element.parentNode
    • 批注:位置相对于有定位的父级定位,无父级或者父级无定位,以body为准
  • 图解如下:
    ![[Pasted image 20221120145840.png]]

定位元素

  • 通常,元素被浏览器自动定位位文档的一部分
  • 定位一个脱离文档流的元素:
	element.style.position = "absolute" ;
	element.style.left = 40px;
	element.style.top = "10px";
- 绝对定位的元素会脱离文档流,不在页面中占据空间
  • The origin inside an offsetParent (for positioning descendants) is just inside the upper-left corner of its border. offsetParent 中的原点(⽤于定位后代),正好在其边框的左上角内

positioning context

  • 每个元素都有一个offsetParent,(有些是父级,有些是祖先)
  • 对于定位过的元素,坐标系(比如:element.style.left)返回的是相对于其offsetParent的位置
  • 默认的offsetParent<body>元素
  • 一些元素定义了一个新的positioning context:
    • position CSS attribute is absolute (element is explicitly positioned)
      • 批注:绝对定位的元素相对于最近定位的父级定位,父级祖级无定位,以initial containing block为基准进行定位
    • position CSS attribute is relative (element is positioned automatically by the browser in the usual way)
      • 批注:相对定位的元素针对自身在文档流中的位置进行偏移
    • This element will become the offsetParent for all its decendents(unless overridden by another positioning context)
      • 批注:这些已经定位的元素会称为其后代元素的的offsetParent

定位子级

  • 图解如下:
    在这里插入图片描述

  • 注意:offsetTopoffsetLeft是子级margin距父级border的距离

元素尺寸(dimensions)

  • 读取尺寸: element.offsetWidthelement.offsetHeight
    • 返回数值包含元素的:contents, padding, border, 但是不包含margin
  • 更新尺寸: element.style.widthelement.style.height
    • 批注:
      • element.offsetWidthelement.offsetHeight
        • 只读属性,不可修改
        • 返回值 = 内容区宽高 + padding + border
      • element.style.widthelement.style.height
        • 可修改
        • 返回值 = 内容区宽高
      • document.clientWidthdocument.clientHeight
        • 只读,不可修改
        • 返回值 = 内容区宽高+padding

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值