首页 > 编程语言 >JavaScript的DOM操作

JavaScript的DOM操作

时间:2024-10-21 09:48:31浏览次数:7  
标签:元素 DOM JavaScript boxEl 操作 document 节点 属性

元素的继承

     class Student extends Person{} 创建一个Student对象继承自Person对象本身会自带Person的属性并且可以创建属于自己的属性

什么是DOM?

  ◼ 前面我们花了很多时间学习JavaScript的基本语法,但是这些基本语法,但是这些语法好像和做网页没有什么关系,和前面学习
  的HTML、CSS也没有什么关系呢?
      这是因为我们前面学习的部分属于ECMAScript,也就是JavaScript本身的语法部分;
      除了语法部分之外,我们还需要学习浏览器提供给我们开发者的DOM、BOM相关的API才能对页面、浏览器进行操作;
  ◼ 前面我们学习了一个window的全局对象,window上事实上就包含了这些内容:
      我们已经学习了JavaScript语法部分的Object、Array、Date等;
      另外还有DOM、BOM部分;
  ◼ DOM:文档对象模型(Document Object Model)
      简称DOM,将页面所有的内容表示为可以修改的对象;
  ◼ BOM:浏览器对象模型(Browser Object Model)
      简称BOM,由浏览器提供的用于处理文档(document)之外的所有内容的其他对象;
      比如navigator、location、history等对象;

深入理解DOM

  浏览器会对我们编写的HTML、CSS进行渲染,同时它又要考虑我们可能会通过JavaScript来对其进行操作:
      于是浏览器将我们编写在HTML中的每一个元素(Element)都抽象成了一个个对象;
      所有这些对象都可以通过JavaScript来对其进行访问,那么我们就可以通过JavaScript来操作页面;
      所以,我们将这个抽象过程称之为文档对象模型(Document Object Model);
  ◼ 整个文档被抽象到document 对象中:
      比如document.documentElement对应的是html元素;
      比如document.body对应的是body元素;
      比如document.head对应的是head元素;
  ◼ 下面的一行代码可以让整个页面变成红色:
  document.body.style.backgroundColor = "red"
  ◼ 所以我们学习DOM,就是在学习如何通过JavaScript对文档进行操作的;

认识DOM Tree

  ◼ 一个页面不只是有html、head、body元素,也包括很多的子元素:
      在html结构中,最终会形成一个树结构;
      在抽象成DOM对象的时候,它们也会形成一个树结构,我们称之为DOM Tree;

document对象

  ◼ Document节点表示的整个载入的网页,它的实例是全局的document对象:
      对DOM的所有操作都是从document 对象开始的;
      它是DOM的入口点,可以从document开始去访问任何节点元素;
  ◼ 对于最顶层的html、head、body元素,我们可以直接在document对象中获取到:
      html元素:<html> = document.documentElement
      body元素:<body> = document.body
      head元素:<head> = document.head
      文档声明:<!DOCTYPE html> = document.doctype

DOM的整体结构

  ◼ DOM相当于是JavaScript和HTML、CSS之间的桥梁
      通过浏览器提供给我们的DOM API,我们可以对元素以及其中的内容做任何事情;
      var htmlEl = document.documentElement;
      var bodyEl = document.body
      var headEl = document.head
      var docTypeEl = document.doctype

      console.log(htmlEl,bodyEl,headEl,docTypeEl)

节点、元素导航

节点(Node)之间的导航(navigator)

  ◼ 如果我们获取到一个节点(Node)后,可以根据这个节点去获取其他的节点,我们称之为节点之间的导航。
  ◼ 节点之间存在如下的关系:
       父节点:parentNode
       前兄弟节点:previousSibling
       后兄弟节点:nextSibling
       子节点:childNodes
       第一个子节点:firstChild
       最后一个子节点:lastChild

元素(Element)之间的导航(navigator)

  ◼ 如果我们获取到一个元素(Element)后,可以根据这个元素去获取其他的元素,我们称之为元素之间的导航。
  ◼ 节点之间存在如下的关系:
       父元素:parentElement
       前兄弟元素:previousElementSibling
       后兄弟元素:nextElementSibling
       子元素:children
       第一个子元素:firstElementChild
       最后一个子元素:lastElementChild

表格(table)元素的导航(navigator)

  ◼ <table> 元素支持 (除了上面给出的,之外) 以下这些属性:
      table.rows — <tr> 元素的集合;
      table.caption/tHead/tFoot — 引用元素 <caption>,<thead>,<tfoot>;
      table.tBodies — <tbody> 元素的集合;
  ◼ <thead>,<tfoot>,<tbody> 元素提供了 rows 属性:
      tbody.rows — 表格内部<tr> 元素的集合;
  ◼ <tr>:
      tr.cells — 在给定 <tr> 中的 <td> 和 <th> 单元格的集合;
      tr.sectionRowIndex — 给定的 <tr> 在封闭的 <thead>/<tbody>/<tfoot> 中的位置(索引);
      tr.rowIndex — 在整个表格中 <tr> 的编号(包括表格的所有行);
  ◼ <td> 和 <th>:
      td.cellIndex — 在封闭的 <tr> 中单元格的编号。

表单(form) 元素导航

  1.form 元素可以直接通过document来获取:document.forms
      var formEl = document.forms[0]
  2.form 元素中的内容可以通过elements来获取
      var elements = formEl.elements
  我们可以通过设置表单元素的name来获取它们
      <form action="">
      <input type="text" name="account" >
      <input type="password" name="password" autocomplete="off">
      <input type="checkbox" name="hobbies" checked>
      <select name="fruits" >
        <option value="apple">苹果</option>
        <option value="orange">橘子</option>

      </select>
    </form>
    <script>
    // 获取form元素
      // var  formEl =document.body.firstElementChild
      var  formEl = document.forms[0]
      // 获取form中的子元素
      var inputEl = formEl.elements.account
      // 
      setTimeout(function(){
        console.log(inputEl.value)
      },2000)
    </script>

获取元素的方法

  ◼ 当元素彼此靠近或者相邻时,DOM 导航属性(navigation property)非常有用。
    但是,在实际开发中,我们希望可以任意的获取到某一个元素应该如何操作呢?
  方法名                      搜索方式        可以在元素上调用?    实时的?
  querySelector              CSS-selector          ✔                -
  querySelectorAll           CSS-selector          ✔                -
  getElementById             id                    -                 -
  getElementsByName          name                  -                ✔
  getElementsByTagName      tag or '*'             ✔                ✔
  getElementsByClassName    class                  ✔                ✔

Node节点的属性

  ◼ 目前,我们已经可以获取到节点了,接下来我们来看一下节点中有哪些常见的属性:
       当然,不同的节点类型有可能有不同的属性;
       这里我们主要讨论节点共有的属性;
  ◼ nodeType属性:
       nodeType 属性提供了一种获取节点类型的方法;
       它有一个数值型值(numeric value);

其他类型可以查看MDN文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Node/nodeType

  ◼ nodeName:获取node节点的名字;
  ◼ tagName:获取元素的标签名词;
  ◼ tagName和nodeName之间有什么不同呢?
      tagName属性仅适用于Element 节点;
      nodeName是为任意Node 定义的:
          ✓ 对于元素,它的意义与tagName相同,所以使用哪一个都是可以的;
          ✓ 对于其他节点类型(text,comment 等),它拥有一个对应节点类型的字符串;

节点的属性-innerHTML、textContent

  ◼ innerHTML 属性
      将元素中的HTML 获取为字符串形式;
      设置元素中的内容;
  ◼ outerHTML 属性
      包含了元素的完整HTML
      innerHTML 加上元素本身一样;
  ◼ textContent 属性
      仅仅获取元素中的文本内容;
  ◼ innerHTML和textContent的区别:
      使用innerHTML,我们将其“作为 HTML”插入,带有所有HTML 标签。
      使用textContent,我们将其“作为文本”插入,所有符号(symbol)均按字面意义处理。
  ◼ nodeValue/data
      用于获取非元素节点的文本内容

节点的其他属性

  ◼ hidden属性:也是一个全局属性,可以用于设置元素隐藏。
  ◼ DOM 元素还有其他属性:
      value
          ✓ <input>,<select> 和 <textarea>(HTMLInputElement,HTMLSelectElement……)的 value。
      href
          ✓ <a href="...">(HTMLAnchorElement)的 href。
      id
          ✓ 所有元素(HTMLElement)的“id” 特性(attribute)的值。
  ◼ class和style我们会在后续专门讲解的

元素的特性attribute

  ◼ 前面我们已经学习了如何获取节点,以及节点通常所包含的属性,接下来我们来仔细研究元素Element。
  ◼ 我们知道,一个元素除了有开始标签、结束标签、内容之外,还有很多的属性(attribute)
  ◼ 浏览器在解析HTML元素时,会将对应的attribute也创建出来放到对应的元素对象上。
      比如id、class就是全局的attribute,会有对应的id、class属性;
      比如href属性是针对a元素的,type、value属性是针对input元素的;
  ◼ 接下来我们学习一下如何获取和设置这些属性。

attribute的分类

  ◼属性attribute的分类:
      标准的attribute:某些attribute属性是标准的,比如id、class、href、type、value等;
      非标准的attribute:某些attribute属性是自定义的,比如abc、age、height等;

attribute的操作

  ◼ 对于所有的attribute访问都支持如下的方法:
      elem.hasAttribute(name) — 检查特性是否存在。
      elem.getAttribute(name) — 获取这个特性值。
      elem.setAttribute(name, value) — 设置这个特性值。
      elem.removeAttribute(name) — 移除这个特性。
      attributes:attr对象的集合,具有name、value属性;
  ◼ attribute具备以下特征:
      // 1.所有的attribute都支持的操作
      console.log(boxEl.hasAttribute("age"),boxEl.hasAttribute("abc"),boxEl.hasAttribute("id"))
      console.log(boxEl.getAttribute("age"),boxEl.getAttribute("abc"),boxEl.getAttribute("id"))
      boxEl.setAttribute("id","cba")
      boxEl.removeAttribute("id")

      var boxArributes = boxEl.attributes
      for (var attr of boxArributes){
        console.log(attr.name,attr.value)
      }

      它们的名字是大小写不敏感的(id 与ID 相同)。
      它们的值总是字符串类型的。

元素的属性property

      ◼ 对于标准的attribute,会在DOM对象上创建与其对应的property属性:
        // 获取box元素
        var boxEl = document.querySelector(".box")
        console.log(boxEl.id,boxEl.title,boxEl.age,boxEl.height)
        var inputEl = document.querySelector("input")
        console.log(inputEl.checked)
        if(inputEl.checked){
          console.log(`checkbox处于选中状态`)
        }
      ◼ 在大多数情况下,它们是相互作用的
          改变property,通过attribute获取的值,会随着改变;
          通过attribute操作修改,property的值会随着改变;
            ✓ 但是input的value修改只能通过attribute的方法;
      ◼ 除非特别情况,大多数情况下,设置、获取attribute,推荐使用property的方式:
          这是因为它默认情况下是有类型的

元素的class、style

      ◼ 有时候我们会通过JavaScript来动态修改样式,这个时候我们有两个选择:
          选择一:在CSS中编写好对应的样式,动态的添加class;
          选择二:动态的修改style属性;
      ◼ 开发中如何选择呢?
          在大多数情况下,如果可以动态修改class完成某个功能,更推荐使用动态class;
          如果对于某些情况,无法通过动态修改class(比如精准修改某个css属性的值),那么就可以修改style属性;
        // 1.获取box
        var boxEl = document.querySelector(".box")
        console.log(boxEl)
        boxEl.onclick = function(){
          // 直接修改style属性
          // boxEl.style.color = "red"
          // boxEl.style.fontSize = "24px"
          // boxEl.style.backgroundColor = "green"
          //2. 动态添加class
          boxEl.className = "active"
        }

元素的className和classList

  ◼ 元素的class attribute,对应的property并非叫class,而是className:
      这是因为JavaScript早期是不允许使用class这种关键字来作为对象的属性,所以DOM规范使用了className;
      虽然现在JavaScript已经没有这样的限制,但是并不推荐,并且依然在使用className这个名称;
  ◼ 我们可以对className进行赋值,它会替换整个类中的字符串。
      var boxEl = document.querySelector(".box")
      // 1.方法一:className
      boxEl.className = "abc"
      var obj = {}
  ◼ 如果我们需要添加或者移除单个的class,那么可以使用classList属性。
  ◼ elem.classList 是一个特殊的对象:
      elem.classList.add (class) :添加一个类
      elem.classList.remove(class):添加/移除类。
      elem.classList.toggle(class) :如果类不存在就添加类,存在就移除它。
      elem.classList.contains(class):检查给定类,返回 true/false。
  ◼ classList是可迭代对象,可以通过for of进行遍历。

元素的style属性

  ◼ 如果需要单独修改某一个CSS属性,那么可以通过style来操作:
      对于多词(multi-word)属性,使用驼峰式camelCase
    boxEl.style.backgroundColor = "red"
  ◼ 如果我们将值设置为空字符串,那么会使用CSS的默认样式:
  ◼ 多个样式的写法,我们需要使用cssText属性:
       boxEl.style.cssText = `
          width:100px;
          height:100px;
          background-color:red;
        `
      不推荐这种用法,因为它会替换整个字符串

元素style的读取- getComputedStyle

    ◼ 如果我们需要读取样式:
        对于内联样式,是可以通过style.*的方式读取到的;
        对于style、css文件中的样式,是读取不到的;
    ◼ 这个时候,我们可以通过getComputedStyle的全局函数来实现:
    var boxEl = document.querySelector(".box")
    console.log(boxEl.style.backgroundColor)
    console.log(getComputedStyle(boxEl).fontSize)

元素的常见操作

创建元素

◼ 前面我们使用过document.write 方法写入一个元素:
    这种方式写起来非常便捷,但是对于复杂的内容、元素关系拼接并不方便;
    它是在早期没有DOM的时候使用的方案,目前依然被保留了下来;
◼ 那么目前我们想要插入一个元素,通常会按照如下步骤:
    步骤一:创建一个元素;
    步骤二:插入元素到DOM的某一个位置;
◼ 创建元素: document.createElement(tag)
var boxEl = document.querySelector(".box")
var h2El = document.createElement("h2")
h2El.innerHTML = "我是标题"
h2El.classList.add("title")
boxEl.append(h2El)

插入元素

◼ 插入元素的方式如下:
  node.append(...nodes or strings) —— 在 node 末尾 插入节点或字符串 ----->子元素的最后,
  node.prepend(...nodes or strings) —— 在 node 开头 插入节点或字符串 ---->子元素的最前方,
  node.before(...nodes or strings) —— 在 node 前面 插入节点或字符串 ----->变成兄弟元素放在前面,
  node.after(...nodes or strings) —— 在 node 后面 插入节点或字符串------->变成兄弟元素放在后面,
  node.replaceWith(...nodes or strings) —— 将 node 替换为给定的节点或字符串。
案例:
    // 将元素插入到boxEl里面
    // 方法一:追加到子元素最后
    boxEl.append(h2El)
    // 追加到子元素最前面
    boxEl.prepend(h2El)
    // 变成兄弟元素,放在前面
    boxEl.before(h2El)
    // 变成兄弟元素,放在后面
    boxEl.after(h2El)
    // 替换
    boxEl.replaceWith(h2El)

移除和克隆元素

   ◼ 移除元素我们可以调用元素本身的remove方法:
      setTimeout(()=>{
        h2El.remove()
      },2000)
   ◼ 如果我们想要复制一个现有的元素,可以通过cloneNode方法:
      可以传入一个Boolean类型的值,来决定是否是深度克隆;
      深度克隆会克隆对应元素的子元素,否则不会
    案例:
      var cloneBoxEl = boxEl.cloneNode(true)
      document.body.append(cloneBoxEl)

旧的元素操作方法

   ◼ 在很多地方我们也会看到一些旧的操作方法:
    parentElem.appendChild(node):
      ✓ 在parentElem的父元素最后位置添加一个子元素
    parentElem.insertBefore(node, nextSibling):
      ✓ 在parentElem的nextSibling前面插入一个子元素;
    parentElem.replaceChild(node, oldChild):
      ✓ 在parentElem中,新元素替换之前的oldChild元素;
    parentElem.removeChild(node):
      ✓ 在parentElem中,移除某一个元素;

元素的大小和滚动

    ◼ clientWidth:contentWith+padding(不包含滚动条)
    ◼ clientHeight:contentHeight+padding
    ◼ clientTop:border-top的宽度
    ◼ clientLeft:border-left的宽度
    ◼ offsetWidth:元素完整的宽度
    ◼ offsetHeight:元素完整的高度
    ◼ offsetLeft:距离父元素的x
    ◼ offsetTop:距离父元素的y
    ◼ scrollHeight:整个可滚动的区域高度
    ◼ scrollTop:滚动部分的高度

window的大小和滚动

    ◼ window的width和height
        innerWidth、innerHeight:获取window窗口的宽度和高度(包含滚动条)
        outerWidth、outerHeight:获取window窗口的整个宽度和高度(包括调试工具、工具栏)
        documentElement.clientHeight、documentElement.clientWidth:获取html的宽度和高度(不包含滚动条)
    ◼ window的滚动位置:
        scrollX:X轴滚动的位置(别名pageXOffset)
        scrollY:Y轴滚动的位置(别名pageYOffset)
    ◼ 也有提供对应的滚动方法:
        方法scrollBy(x,y) :将页面滚动至 相对于当前位置的 (x, y) 位置;
        方法scrollTo(pageX,pageY) 将页面滚动至 绝对坐标

标签:元素,DOM,JavaScript,boxEl,操作,document,节点,属性
From: https://www.cnblogs.com/hdc-web/p/18488407

相关文章

  • JavaScript的事件处理
    认识事件处理◼Web页面需要经常和用户之间进行交互,而交互的过程中我们可能想要捕捉这个交互的过程:比如用户点击了某个按钮、用户在输入框里面输入了某个文本、用户鼠标经过了某个位置;浏览器需要搭建一条JavaScript代码和事件之间的桥梁;当某个事件发生时,让JavaScr......
  • Dom阶段实战案例
    window定时器◼有时我们并不想立即执行一个函数,而是等待特定一段时间之后再执行,我们称之为“计划调用(schedulingacall)”。◼目前有两种方式可以实现:setTimeout允许我们将函数推迟到一段时间间隔之后再执行。setInterval允许我们重复运行一个函数,从一段时间间隔......
  • JavaScript递归按条件过滤掉子级数据
    有一个子父级树形结构的数据,现需要递归遍历,找到类型为‘1’的数据,过滤子级,最后返回树形结构数据代码如下//调用方法,返回按要求过滤后的数据constnewArr=this.clearChildrenOfTypeIndex(arr)//定义过滤方法clearChildrenOfTypeIndex(tree){//避免原始数组被直接修改......
  • 2024-10-19:用go语言,给定一个正整数 k 和初始数组 nums = [1], 可以执行两种操作:将数组
    2024-10-19:用go语言,给定一个正整数k和初始数组nums=[1],可以执行两种操作:将数组中任一元素加一,或复制数组中任意元素并将其附加到数组末尾。求使得数组元素之和大于或等于k所需的最少操作次数。输入:k=11。输出:5。解释:可以对数组nums=[1]执行以下操作:将元......
  • 操作系统学习笔记-1.2操作系统的发展历程,运行机制
    文章目录批处理操作系统1.**单道(Single-ProgrammedSystem)**特点:举例:2.**多道(Multi-ProgrammingSystem)**特点:3.**单道与多道的对比**分时操作系统与实时操作系统1.**分时操作系统(Time-SharingOperatingSystem)**概念:特点:应用场景:举例:2.**实时操作系统(Real-Tim......
  • MySQL5.7 InnoDB在线DDL操作
    MYSQL官方文档:https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl.html目录在线DDL原理在线DDL支持情况IndexOperations(索引操作)PrimaryKeyOperations(主键操作)ColumnOperations(列操作)TableOperations(表操作)pt-osc方式在线DDL和pt-osc对比参考在线DDL原理MySQL5.6......
  • KeyShot基础操作5 - 动画篇
    --本篇导航--动画界面动画类型动画时间轴导出动画一些例子注:本人目前只会简单的动画,摄像机运镜、速度曲线这些还控制不好。以下均为简单演示。动画界面KeyShot中的动画每次只能是一个动作,如果需要对同一个对象创建复杂的动画,就需要对其多次添加不同的动画效果。做......
  • 使用 JavaScript (Node.js) 实现验证码识别与自动化登录
    安装所需依赖首先,确保你已经安装了Node.js。然后,使用npm安装所需的库:bashnpminstallaxiosjimptesseract.js2.下载验证码图片使用axios下载验证码图片并保存到本地:更多内容联系1436423940javascriptconstfs=require('fs');constaxios=require('axios');......
  • 文件的基本操作
    创建文件删除文件在这里我们可以看到,删除文件这个系统调用也是需要用文件名去目录表中寻找文件的打开文件当用户对一个文件实施多次读/写等操作时,每次都要从检索目录开始.为了避免多次重复地检索目录,大多数操作系统要求,当用户首次对某文件发出操作请求时,须先利用系统调用......
  • 三,Random
    Random类详解在Java编程中,Random类是java.util包中用于生成随机数的类。它提供了多种方法来生成随机数,这些方法可以生成不同类型的随机数,包括整数、浮点数等。本文将详细探讨Random类的用法、构造方法和成员方法,包括nextInt()、nextDouble()等。Random类概述Random类是Java中用......