HTML-DOM模型

1.DOM模型

window对象下的document对象就是DOM模型。 DOM描绘了一个层次化的节点树,每一个节点就是一个html标签,而且每一个节点也是一个DOM对象。

2.操作DOM

2.1.获取DOM对象常用方法

获取DOM对象的常用方法有如下几种:

  1. getElementById() 通过元素的ID属性 获取DOM对象,获取的是一个DOM对象
  2. getElementsByTagName() 通过元素的标签名 获取DOM对象,获取的是一组DOM对象
  3. getElementsByClassName() 通过元素的class属性 获取DOM对象,获取的是一组DOM对象
  4. getElementsByName() 通过元素的name属性 获取DOM对象,获取的是一组DOM对象
html 复制代码
	<p id="one">这是一个p标签</p>
  <p class="first">这是一个p标签</p>
  <p class="first">这是一个p标签</p>
  <p name="username">这是一个p标签</p>
  <p name="username">这是一个p标签</p>
  <script>
      let oneObj = document.getElementById('one');
      oneObj.style.color = 'red';     //只有第一个p标签字体变红色
      let pArr = document.getElementsByTagName('p');
      console.log(pArr.length);       //获取所有p标签对象,是数组,长度为5
      let firstArr = document.getElementsByClassName('first');
      console.log(firstArr.length);   //获取所有class为first的对象,是数组,长度为2
      let userArr = document.getElementsByName('user');
      console.log(userArr.length);    //获取所有name属性为user的对象,是数组,长度为2
  </script>

上面代码中所涉及的知识点: 给DOM对象设置CSS样式的语法: DOM对象.style.样式属性名 = '样式值'

2.2.其它获取DOM对象的方法(扩展)

  1. document.documentElement 获取html对象
  2. document.body 获取body对象
  3. document.querySelector() 通过选择器获取一个DOM对象
  4. document.querySelectorAll() 通过选择器获取一组DOM对象
html 复制代码
<div>
  <p>这是一个p标签</p>
  <p>这是一个p标签</p>
</div>
<script>
    let htmlObj = document.documentElement;
    htmlObj.style.backgroundColor = 'red';       //设置html背景色
    let bodyObj = document.body;
    bodyObj.style.fontSize = '36px';             //设置body中所有元素的字体大小
    let pObj = document.querySelector('div p');
    pObj.style.color = 'blue';                   //第一个p标签有效
    let pArr = document.querySelectorAll('div p');
    console.log(pArr.length);                    //数组长度为2
</script>

2.3.获取DOM对象的时机

  1. 要特别注意一点,javaScript代码要写在body的最后。因为,必须要保证html代码全部加载完毕之后,才执行javaScript代码,才能获取DOM对象。
  2. 如果一定要将javaScript代码放在html之前那么要做如下写法:
html 复制代码
<script>
    //文档就绪函数
    window.onload = function(){
      var obj = document.getElementById("one");
      obj.innerHTML = 'hello world!';
    };
</script>
<p id="one"></p>

window.onload事件:浏览器完成页面加载(包括图片等资源)后立即触发,此事件的处理函数就叫做"文档就绪函数"。 如果使用window.onload事件的话,我们就可以将javaScript代码写在网页的任何一个部分,或者是任何一个外部js文件中。

2.4.操作DOM对象属性

操作DOM对象的属性,常用的都有两种方式:

  1. 通过DOM对象直接操作属性
html 复制代码
<p>hello world</p>
<input type="text">
<script>
  document.getElementsByTagName('p')[0].title = 'aaaa';
  let userName = document.getElementsByTagName('input')[0];
  userName.value = 'zhangsan';
  userName.disabled = true;
</script>
  1. 通过DOM对象中封装的方法操作属性 setAttribute() 设置元素的属性值 getAttribute() 获取元素的属性值 removeAttribute() 移除元素的属性值
html 复制代码
<p>hello world</p>
<input type="text">
<script>
  document.getElementsByTagName('p')[0].setAttribute('title','aaaa');
  let userName = document.getElementsByTagName('input')[0];
  userName.setAttribute('value','zhangsan');
  userName.setAttribute('disabled',true);
  userName.removeAttribute('disabled');
  console.log(userName.getAttribute('value'))
</script>

2.5.DOM对象中的常用属性

  1. innerHTML属性:用于设置或获取HTML 元素中的内容。
html 复制代码
<p id="one">
  <span>这是一个段落</span>
</p>
<script>
  let obj = document.getElementById('one');
  console.log(obj.innerHTML);                  //<span>这是一个段落</span>
  obj.innerHTML = '<span>hello world!</span>';
</script>
  1. innerText属性:用于设置或获取HTML 元素中的纯文本
html 复制代码
<p id="one">
  <span>这是一个段落</span>
</p>
<script>
  let obj = document.getElementById('one');
  console.log(obj.innerText);                  //这是一个段落
  obj.innerText = 'hello world!';
</script>
  1. className属性:用于设置或获取DOM对象的类样式
html 复制代码
<div id="one" class="first"></div>
<script>
  let obj = document.getElementById('one');
  console.log(obj.className);                //first
  obj.className = 'two';
</script>
  1. style属性:用于设置或获取DOM对象的style样式
html 复制代码
<div id="one">我是一个div</div>
<script>
  let obj = document.getElementById('one');
  obj.style.width = '300px';
  obj.style.height = '200px';
  obj.style.backgroundColor = 'blue';
  obj.style.fontSize = '24px';
  obj.style.color = '#fff';
  obj.style.border = 'solid 10px red';
  obj.style.display = 'block';          //设置DOM对象的显示和隐藏
</script>

注意:

在使用javaScript操作DOM对象的CSS样式时,由于javaScript不能识别 "-" 字符,所以,所有CSS样式的书写,要一律从xxxx-xxxx形式转换为xxxxXxxx的形式。

2.6.遍历DOM数组

在上面的例子中,都是使用getElementById获取一个DOM对象进行操作。 但在实际开发中,经常会同时操作多个DOM对象,此时,可以使用循环来遍历DOM数组。

html 复制代码
<p>我是p标签</p>
<p>我是p标签</p>
<p>我是p标签</p>
<script>
  let arr = document.getElementsByTagName('p');
  for(let i=0;i<arr.length;i++){
    arr[i].style.color = 'red';
    arr[i].style.fontSize = '36px';
  }
</script>

3.代码调试

调试是指在一个脚本中找出并修复错误的过程。在浏览器中调试是开发过程中常见的操作,它可以帮助你查找和修复代码中的错误,也可以让我们一步步地跟踪代码以查看当前实际运行情况。在这里我们将会使用 Chrome(谷歌浏览器),因为它拥有足够多的功能,其他大部分浏览器的功能也与之类似。

3.1 打开浏览器的开发者工具

  • Google Chrome :右键点击页面任意位置,选择"检查"或按下Ctrl + Shift + ICmd + Option + I(Mac)或者使用快捷键 F12来打开开发者工具。然后切换到"Console"(控制台)选项卡。
  • Mozilla Firefox :同样,使用Ctrl + Shift + ICmd + Option + I(Mac)来打开开发者工具,然后切换到"Web Console"(Web控制台)选项卡。
  • Microsoft Edge :使用F12键或右键点击页面并选择"检查元素"打开开发者工具,然后切换到"Console"选项卡。

3.2 设置界面语言

3.3 重现错误

html 复制代码
<html>
  <head>
    
    <title>Demo: 使用 Chrome DevTools 调试 JavaScript</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
      h1 {
        font-size: 1.5em
      }
      input, button {
        min-width: 72px;
        min-height: 36px;
        border: 1px solid grey;
      }
      label, input, button {
        display: block;
      }
      input {
        margin-bottom: 1em;
      }
    </style>
  </head>
  <body>
    <h1>使用 Chrome DevTools 调试 JavaScript</h1>
    <label for="num1">数字 1</label>
    <input placeholder="数字 1" id="num1">
    <label for="num2">数字 2</label>
    <input placeholder="数字 2" id="num2">
    <button>数字 1和数字 2相加 </button>
    <p></p>
     
  </body>
</html>
<script>
  function onClick() {
  if (inputsAreEmpty()) {
    label.textContent = 'Error: 有一个或者两个文本框值为空';
    return;
  }
  updateLabel();
}
function inputsAreEmpty() {
  if (getNumber1() === '' || getNumber2() === '') {
    return true;
  } else {
    return false;
  }
}
function updateLabel() {
  var addend1 = getNumber1();
  var addend2 = getNumber2();
  var sum = addend1 + addend2;
  label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
}
function getNumber1() {
  return inputs[0].value;
}
function getNumber2() {
  return inputs[1].value;
}
var inputs = document.querySelectorAll('input');
var label = document.querySelector('p');
var button = document.querySelector('button');
button.addEventListener('click', onClick);

</script>

运行结果:

在本例中,1 + 2 的结果是 12。应该是 3。

3.4 调试并修复错误

3.4.1 熟悉"来源"面板界面

开发者工具提供了许多不同的工具来处理不同的任务,例如更改 CSS、分析网页加载性能以及监控网络请求。您可以在 Sources 面板中调试 JavaScript。

  1. 按 Command+Option+J (Mac) 或 Control+Shift+J(Windows、Linux)打开开发者工具。此快捷方式可打开控制台 面板,并点击来源标签页。

2、Sources 面板界面包含 3 个部分:

  1. 文件导航器窗格。此处列出了网页请求的每个文件。
  2. 代码编辑器 窗格。在文件导航器窗格中选择文件后,此处会显示该文件的内容。
  3. JavaScript 调试 窗格。用于检查网页 JavaScript 的各种工具。如果开发者工具窗口较宽,此窗格会显示在 Code Editor 窗格的右侧。

3.4.2 使用断点暂停代码

调试这类问题的常用方法是在代码中插入大量 console.log() 语句,以便在脚本执行时检查值。由于前端代码相对比较简单,函数的代码量较少,这也是目前非常有效的做法。

html 复制代码
function updateLabel() {
  var addend1 = getNumber1();
  console.log('addend1:', addend1);
  var addend2 = getNumber2();
  console.log('addend2:', addend2);
  var sum = addend1 + addend2;
  console.log('sum:', sum);
  label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
}

console.log() 方法可以完成工作,但断点可以更快地完成工作。通过断点,您可以在代码执行过程中暂停代码,并在该时刻检查所有值。与 console.log() 方法相比,断点具有一些优势:

  • 使用 console.log() 时,您需要手动打开源代码,找到相关代码,插入 console.log() 语句,然后重新加载页面,才能在控制台中查看这些消息。使用断点,您甚至无需了解代码的结构即可暂停相关的代码。
  • 在 console.log() 语句中,您需要明确指定要检查的每个值。使用断点,开发者工具会及时显示所有变量的值。有时,有些变量在您不知情的情况下会影响您的代码。

简而言之,与 console.log() 方法相比,断点可以帮助您更快地查找和修复 bug。

如果您退一步想一想应用的工作原理,可以有据地猜测,系统会在与 Add Number 1 and Number 2 按钮关联的 click 事件监听器中计算不正确的总和 (5 + 1 = 51)。因此,您可能需要在 click 监听器执行前后暂停代码。事件监听器断点可让您实现以下目的:

  1. JavaScript 调试 窗格中,点击事件监听器断点 以展开该部分。开发者工具会显示一系列可展开的事件类别,例如 AnimationClipboard
  2. 点击鼠标 事件类别旁边的展开 。 开发者工具会显示鼠标事件列表,例如 clickmousedown。每个事件旁都有一个复选框。
  3. 选中 click 复选框。开发者工具现已设置为在执行任何 click 事件监听器时自动暂停。
  4. 返回演示,再次点击 Add Number 1 and Number 2 (添加编号 1 和编号 2)。开发者工具会暂停演示,并在 Sources 面板中突出显示一行代码。在以下代码行上,开发者工具应暂停:

注意:如果您是在其他代码行暂停,请按 Resume Script Execution 图标 ,直到暂停位置正确。

事件监听器断点 只是开发者工具中提供的众多断点类型之一。您需要记住所有不同的类型,因为每种类型最终都可以帮助您尽快调试不同的场景。如需了解每种类型的使用时机和使用方式,请参阅使用断点暂停代码

3.4.3.单步调试代码

导致 bug 的一种常见原因是脚本执行顺序有误。您可以通过单步调试代码一次一行地检查代码执行情况,并弄清楚代码的执行顺序与预期不同。立即试用:

  1. 在开发者工具的 Sources 面板中,点击 Step into next function call 图标


    ,以一次一行的形式逐步执行 onClick() 函数。开发者工具会突出显示下面这行代码:

html 复制代码
if (inputsAreEmpty()) {
  1. 点击 Step over next function call【跳过下一个函数调用】 图标


    。 开发者工具会执行 inputsAreEmpty(),而不会进入它。请注意开发者工具如何跳过几行代码。这是因为 inputsAreEmpty() 的求值结果为 false,所以 if 语句的代码块未执行。

相比之下,

这就是单步调试代码的基本思路。

3.4.4 设置代码行断点

代码行断点是最常见的断点类型。如果您想在执行到某一行代码时暂停,请使用代码行断点。

使用代码行断点之前,首先您应该先对自己的代码进行简要评估,按照业务的执行顺序,估计出错误代码的范围,一般代码行断点设在此范围之前。

  1. 请查看 updateLabel() 中的最后一行代码:
html 复制代码
label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
  1. 在代码左侧,您可以看到这行代码的行号,即 53 。点击 53 。开发者工具会在 53 上方显示一个蓝色图标。这意味着这行代码上有一个代码行断点。现在,开发者工具始终会在执行这行代码之前暂停。
  1. 点击继续执行脚本


    。脚本会继续执行,直到第 32 行。在第 29、30 和 31 行,开发者工具以内嵌方式显示 addend1、addend2 和 sum 的值。

在此示例中,开发者工具在第 53 行代码行断点处暂停。

3.4.5 检查变量值

addend1、addend2 和 sum 的值看起来很可疑。它们是用英文引号引起来的,这意味着它们是字符串。这是一个很好的假设,可以解释错误的原因。现在可以收集更多信息了。开发者工具提供了许多用于检查变量值的工具。

方法 1:Scope【本地】 窗格

在某行代码上暂停时,Scope 【本地】窗格会显示当前定义的局部和全局变量,以及每个变量的值。其中还会显示闭包变量(如果适用)。双击变量值即可对其进行修改。如果未在任何代码行暂停,则 Scope 【本地】窗格为空。

方法 2:监视表达式

监视表达式标签页可让您监控变量的值随时间的变化。顾名思义,监视表达式不仅限于变量。您可以将任何有效的 JavaScript 表达式存储在监视表达式中。立即试用:

  1. 点击观看标签页。

  2. 点击添加表达式


  3. 输入 typeof sum。

  4. 按 Enter 键。开发者工具会显示 typeof sum: "string"。冒号右侧的值是监视表达式的结果。

上面的屏幕截图显示了创建 typeof sum 监视表达式后的 Watch Expression 窗格(右下角)。如果开发者工具窗口较大,Watch Expression 窗格位于右侧,在 Event Listener Breakpoints 窗格的上方。

就像猜测一样,sum 的求值结果本应是数字,而实际结果却是字符串。现在,您已确认这是导致 bug 的原因。

方法 3:控制台

除了查看 console.log() 消息之外,您还可以使用控制台对任意 JavaScript 语句求值。在调试方面,您可以使用控制台测试 bug 的潜在解决方法。立即试用:

  1. 如果您尚未打开控制台抽屉式导航栏,请按 Esc 将其打开。它会在开发者工具窗口底部打开
  1. 在控制台中,输入 parseInt(addend1) + parseInt(addend2)。此语句之所以有效,是因为您暂停了 addend1 和 addend2 在范围内的代码行。

注意:需要根据提示输入:允许粘贴

  1. 按 Enter 键。开发者工具会评估语句并输出 3,这是您希望演示生成的结果。

上面的屏幕截图显示了评估 parseInt(addend1) + parseInt(addend2) 后的 Console 抽屉式导航栏。

3.4.6 应用解决方案

您已找到该 bug 的修复方案。接下来就是尝试通过修改代码并重新运行演示来尝试修复。您无需离开开发者工具即可应用修复。您可以直接在开发者工具界面中修改 JavaScript 代码。立即试用:

  1. 点击继续执行脚本


  1. 代码编辑器中,将第 53 行 var sum = addend1 + addend2 替换为 var sum = parseInt(addend1) + parseInt(addend2)。

  2. 按 Command + S (Mac) 或 Ctrl + S(Windows、Linux)以保存更改。

  3. 点击 停用断点


    。 其颜色会变为蓝色,表示处于活动状态。完成此设置后,开发者工具会忽略您已设置的任何断点。

  1. 尝试使用不同的值测试演示。演示现在会正确计算。

注意 :此工作流只会修复在浏览器中运行的代码。它不会为访问您的网页的所有用户修正代码。为此,您需要修正服务器上的代码。不过,您可以在开发者工具中修改文件,并通过工作区将文件保存到来源中

要点 :从 Chrome 105 版开始,您可以实时修改已暂停的函数

3.5 小结

Chrome提供了强大的开发者工具,使开发者能够在浏览器中调试和优化代码。除了前文外,还包括:条件断点、XHR断点、代码搜索、性能分析、网络面板、代码预处理器、移动设备模拟 以及**Remote Debugging等等,**请大家在平时的开发过程中,注重积累。

相关推荐
腾讯TNTWeb前端团队3 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰6 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪6 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪7 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy7 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom8 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom8 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom8 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom8 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom8 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试