回到基础:什么是DOM及DOM操做?

译者:前端小智
来源:valentinog

我的专栏 ES6 深刻浅出已上线,深刻ES6 ,经过案例学习掌握 ES6 中新特性一些使用技巧及原理,持续更新中,←点击可订阅。html

点赞再看,养成习惯

本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了不少个人文档,和教程资料。欢迎Star和完善,你们面试能够参照考点复习,但愿咱们一块儿有点东西。前端

文本主要介绍文档对象模型(DOM),了解什么是DOM操做,以及如何使用砶 DOM API 与 JS 中的 Web 页面进行交互。node

什么是 DOM ?

DOM(文档对象模型)是针对于xml可是扩展用于HTML的应用程序编程接口,定义了访问和操做HTML的文档的标准。git

W3C文档对象模型是中立于平台和语言之间的接口,它容许程序和脚本动态的访问和更新文档的内容、结构、样式。总之HTML是关于如何获取、修改、添加和删除HTML元素的标准。github

DOM 分层节点

DOM的分层节点通常被称做是DOM树,树中的全部节点均可以经过脚本语言例如JS进行访问,全部HTMlL元素节点均可以被建立、添加或者删除。web

在DOM分层节点中,页面就是用分层节点图表示的。面试

  • 整个文档是一个文档节点,就想是树的根同样。
  • 每一个HTML元素都是元素节点。
  • HTML元素内的文本就是文本节点。
  • 每一个HTML属性时属性节点。

当我们访问一个web页面时,浏览器会解析每一个HTML元素,建立了HTML文档的虚拟结构,并将其保存在内存中。接着,HTML页面被转换成树状结构,每一个HTML元素成为一个叶子节点,链接到父分支。
考虑如下 Html 结构:编程

<!DOCTYPE html>
<html lang="en">
<head>
    <title>A super simple title!</title>
</head>
<body>
<h1>A super simple web page!</h1>
</body>
</html>

在这个结构的顶部有一个document,也称为根元素,它包含另外一个元素:htmlhtml元素包含一个head,而 head 又有一个title。 而后body 包含一个h1。 每一个HTML元素都由特定类型(也称为接口)表示,而且可能包含文本或其余嵌套元素:数组

document (HTMLDocument)
  |
  | --> html (HTMLHtmlElement)
          |  
          | --> head (HtmlHeadElement)
          |       |
          |       | --> title (HtmlTitleElement)
          |                | --> text: "A super simple title!"
          |
          | --> body (HtmlBodyElement)
          |       |
          |       | --> h1 (HTMLHeadingElement)
          |              | --> text: "A super simple web page!"

每一个HTML元素都来自Element,但其中很大一部分都是专用的。 我们能够检查原型以查找元素所属的“种类”。 例如,h1元素是HTMLHeadingElement浏览器

document.querySelector('h1').__proto__

// Output: HTMLHeadingElement

HTMLHeadingElement则是HTMLElement的后代:

document.querySelector('h1').__proto__.__proto__

// Output: HTMLElement

此时(特别是初学者)可能会对documentwindow之间的区别产生一些混淆。接下来看看它们有何不一样!

document 和 window 之间的区别

简单来讲,documentwindow的一个对象属性。window 对象表示浏览器中打开的窗口。若是文档包含框架(frameiframe 标签),浏览器会为 HTML 文档建立一个 window 对象,并为每一个框架建立一个额外的 window 对象。全部的全局函数和对象都属于 window 对象的属性和方法。

区别:

  1. window 指窗体。document指页面。documentwindow的一个子对象。
  2. 用户不能改变 document.location(由于这是当前显示文档的位置)。可是,能够改变window.location (用其它文档取代当前文档)window.location自己也是一个对象,而document.location不是对象。

document接口有许多实用方法,好比querySelector(),它是用于查找给定页面内HTML元素的方法:

document.querySelector('h1');

window表示当前的浏览器,下面代码与上面等价:

window.document.querySelector('h1');

固然,更常见的是用第一种方式。

window是一个全局对象,能够从浏览器中运行的任何JS代码直接访问。 window暴露了不少属性和方法,如:

window.alert('Hello world'); // Shows an alert
window.setTimeout(callback, 3000); // Delay execution
window.fetch(someUrl); // make XHR requests
window.open(); // Opens a new tab
window.location; // Browser location
window.history; // Browser history
window.navigator; // The actual user agent
window.document; // The current page

由于这些属性和方法也是全局的,因此也能够这样访问它们

alert('Hello world'); // Shows an alert
setTimeout(callback, 3000); // Delay execution
fetch(someUrl); // make XHR requests
open(); // Opens a new tab
location; // Browser location
history; // Browser history
navigator; // The actual user agent
document;// The current page

其中有些我们都已经很熟悉了,如setTimeout() 的方法。 例如,当我们想要得知当前用户的浏览器语言时,window.navigator就很是有用:

if (window.navigator) {
  var lang = window.navigator.language;
  if (lang === "en-US") {
    // show something
  }

  if (lang === "it-IT") {
    // show something else
  }
}

DOM 经常使用方法

获取节点

// 经过id号来获取元素,返回一个元素对象
document.getElementById(idName) 
      
// 经过name属性获取id号,返回元素对象数组 
document.getElementsByName(name)  
   
// 经过class来获取元素,返回元素对象数组
document.getElementsByClassName(className)   

// 经过标签名获取元素,返回元素对象数组
document.getElementsByTagName(tagName)

获取/设置元素的属性值:

// 括号传入属性名,返回对应属性的属性值
element.getAttribute(attributeName)

// 传入属性名及设置的值
element.setAttribute(attributeName,attributeValue)

建立节点Node

// 建立一个html元素,这里以建立h3元素为例
document.createElement("h3")

// 建立一个文本节点;
document.createTextNode(String);

// 建立一个属性节点,这里以建立class属性为例
document.createAttribute("class");

增添节点

// 往element内部最后面添加一个节点,参数是节点类型
element.appendChild(Node);

// 在element内部的中在existingNode前面插入newNode
elelment.insertBefore(newNode,existingNode);

删除节点

//删除当前节点下指定的子节点,删除成功返回该被删除的节点,不然返回null
element.removeChild(Node)

DOM经常使用属性

获取当前元素的父节点

// 返回当前元素的父节点对象
element.parentNode

获取当前元素的子节点

// 返回当前元素全部子元素节点对象,只返回HTML节点
element.chlidren

// 返回当前元素多有子节点,包括文本,HTML,属性节点。(回车也会当作一个节点)
element.chilidNodes

// 返回当前元素的第一个子节点对象
element.firstChild

// 返回当前元素的最后一个子节点对象
element.lastChild

获取当前元素的同级元素

// 返回当前元素的下一个同级元素 没有就返回null
element.nextSibling

// 返回当前元素上一个同级元素 没有就返回 null
element.previousSibling

获取当前元素的文本

// 返回元素的全部文本,包括html代码
element.innerHTML

// 返回当前元素的自身及子代全部文本值,只是文本内容,不包括html代码
element.innerText

获取当前节点的节点类型

// 返回节点的类型,数字形式(1-12)
// 常见几个1:元素节点,2:属性节点,3:文本节点。
node.nodeType

设置样式

// 设置元素的样式时使用style
element.style.color=“#eea”;

DOM 操做

DOM中的每一个HTML元素也是一个节点,能够像这样查找节点:

document.querySelector('h1').nodeType;

上面会返回1,它是Element类型的节点的标识符,还能够检查节点名称:

document.querySelector('h1').nodeName;

"H1"

上面的示例返回大写的节点名。可是须要理解的最重要的概念是,我们主要使用DOM中的两种类型的节点:

  • 元素节点
  • 文本节点

建立元素节点,能够经过 createElement方法:

var heading = document.createElement('h1');

建立文本节点,可能经过 createTextNode 方法:

var text = document.createTextNode('Hello world');

接着将两个节点组合在一块儿,而后添加到 body 上:

var heading = document.createElement('h1');
var text = document.createTextNoe('Hello world');
heading.appendChild(text);
document.body.appendChild(heading)

在学习Dom操做时候,这些方法须要牢记并熟练使用的。

目前像我们用这种方式建立和操做元素,是属于命令式DOM操做。现代前端库经过支持声明性方法来解决这个问题,如 JQuery,我们能够声明须要什么HTML元素,其它就由库来完成。

DOM 操做和 jQuery

大部分可能会想,我们直接使用 JQ 不就好了,为啥还要用如createElement这些原生的方法,多费劲。

请注意jQuery正在渐渐消失。Bootstrap 5将把它从依赖项中删除,还有不少项目也在删除它。这背后有一个合理的缘由:原生DOM API提供了大量像JQ这样操做DOM的简便方法,足以替代jQuery一些经常使用的DOM操做。

若是只是想进行简单的交互和操做,请使用普通的JS。我们甚至能够建立本身的迷你框架来抽象最多见的操做:建立元素、追加、建立文本。

总结

DOM是浏览器建立并保留在内存中的网页的虚拟副本。建立、修改、删除 HTML 元素,这些属于 “DOM 操做”。在过去即便对于更简单的任务,我们也要依赖于 jQuery,但今天原生 API 已经互相兼容而且足够成熟足以替代 jQuery 了。

jQuery不会很快消失,可是每一个JS开发人员都必须知道如何使用原生API操做DOM。这样作有不少缘由,额外的库增长了JS应用程序的加载时间和大小,更不用说DOM操做在技术面试也常常出现。

操做 DOM 最经常使用的方法是 document.createElement() 用于建立新的 HTML 元素,document.createTextNode() 用于在 DOM 内建立文本节点。须要注意的是 .appendChild() 用于将新的 HTML 元素或文本节点附加到现有元素。

虽然很好的了解本机 API 是很好的,可是现代前端库也提供了不容置疑的好处。尽管用“原生” JS 去构建大型JS 程序确实是可行的,但有时 Angular、React、Vue能够提供不少帮助。仅使用 JavaScript 来处理更简单的原型和中小型应用也是明智之举。

原文:https://www.valentinog.com/bl...

代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具 Fundebug

交流

干货系列文章汇总以下,以为不错点个Star,欢迎 加群 互相学习。

https://github.com/qq44924588...

我是小智,公众号「大迁世界」做者,对前端技术保持学习爱好者。我会常常分享本身所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,便可看到福利,你懂的。

clipboard.png

相关文章
相关标签/搜索