**DOM**:Document Object Model
[[mozilla.org]](https://developer.mozilla.org/zh-CN/docs/Web/API/Document_Object_Model/Introduction)
文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来。
一个web页面是一个文档。这个文档可以在浏览器窗口或作为HTML源码显示出来。但上述两个情况中都是同一份文档。文档对象模型(DOM)提供了对同一份文档的另一种表现,存储和操作的方式。 DOM是web页面的完全的面向对象表述,它能够使用如 JavaScript等脚本语言进行修改。
所有操作和创建web页面的属性,方法和事件都会被组织成对象的形式(例如, ``document`` 对象表示文档本身, ``table`` 对象实现了特定的 ``HTMLTableElement`` DOM 接口来访问HTML 表格等)。下述介绍基于 Gecko浏览器的 DOM 面向对象引用。
----
目录:
[TOC]
----
## DOM 和 JavaScript
DOM 并不是一个编程语言,但如果没有DOM, JavaScript 语言也不会有任何网页,XML页面以及涉及到的元素的概念或模型。在文档中的每个元素— 包括整个文档,文档头部, 文档中的表格,表头,表格中的文本 — 都是文档所属于的文档对象模型(DOM)的一部分,因此它们可以使用DOM和一个脚本语言如 JavaScript,来访问和处理。
开始的时候,JavaScript和DOM是交织在一起的,但它们最终演变成了两个独立的实体。JavaScript可以访问和操作存储在DOM中的内容,因此我们可以写成这个近似的等式:
>[info] API (web 或 XML 页面) = DOM + JS (脚本语言)
DOM 被设计成与特定编程语言相独立,使文档的结构化表述可以通过单一,一致的API获得。尽管我们在本参考文档中会专注于使用JavaScript, 但DOM 也可以使用其他的语言来实现, 以Python为例,代码如下:
~~~Python
# Python DOM example
import xml.dom.minidom as m
doc = m.parse("C:\\Projects\\Py\\chap1.xml");
doc.nodeName # DOM property of document object;
p_list = doc.getElementsByTagName("para");
~~~
获取更多在网页上使用JavaScript的信息,可以参考 [JavaScript technologies overview](https://developer.mozilla.org/zh-CN/docs/%E4%BD%BF%E7%94%A8Javascript%E5%92%8CDOM_Interfaces%E6%9D%A5%E5%A4%84%E7%90%86HTML).
## 如何访问 DOM?
每个web浏览器都会使用一些文档对象模型,从而使页面可以被脚本语言访问。
当您在创建一个脚本时-无论是使用内嵌 ``<script>``元素或者使用在web页面脚本加载的方法— 您都可以使用`` document`` 或 ``window ``元素的API来操作文档本身或获取文档的子类(web页面中的各种元素)。
## 重要的数据类型
需要注意在API中传入的不同的数据类型。在API参考文档中的语法实例通常会使用``element(s) ``指代节点,使用``nodeList(s)``或 element(s)来指代节点数组,使用 ``attribute(s)``来指代属性节点。
下面的表格简单则描述了这些数据类型。
名称 | 说明 |
------------| --------
``document`` | 当一个成员返回 ``document``对象 (例如,元素的 ownerDocument 属性返回它所属于的 ``document``) ,这个对象就是``document``对象本身。 [DOM document Reference](https://developer.mozilla.org/en-US/docs/Web/API/document) 一章对 document 对象进行了描述。
``element`` | ``element`` 是指由 DOM API 中成员返回的类型为 element 的一个元素或节点。 例如, ``document.createElement()`` 方法会返回一个 ``node`` 的对象引用,也就是说这个方法返回了在DOM中创建的``element``。 ``element`` 对象实现了 DOM ``Element`` 接口以及更基本的 ``Node`` 接口。
``nodeList`` | ``nodeList`` 是一个元素的数组,如从`` document.getElementsByTagName()``方法返回的就是这种类型。 ``nodeList`` 中的条目由通过下标有两种方式进行访问:<br>- list.item(1) <br>- list[1] <br>两种方式是等价的,第一种方式中 ``item()`` 是 ``nodeList`` 对象中的单独方法。 后面的方式则使用了经典的数组语法来获取列表中的第二个条目。
``attribute`` | 当 ``attribute`` 通过成员函数 (例如,通过`` createAttribute()``方法) 返回时,它是一个为属性暴露出专门接口的对象引用。DOM中的属性也是节点,就像元素一样,只不过可能会很少使用它。
``namedNodeMap`` | ``namedNodeMap`` 和数组类似,但是条目是由name或index访问的,虽然后一种方式仅仅是为了枚举方便,因为在 list 中本来就没有特定的顺序。 出于这个目的, ``namedNodeMap`` 有一个 item() 方法,也可以从 `` namedNodeMap`` 添加或移除条目。
## DOM 接口
许多对象会对多个不同的接口进行实现。以table对象举例:
table对象实现了 HTML Table Element Interface, 其中包括``createCaption`` 和 ``insertRow`` 方法。
table对象同时也是一个HTML元素, table 也实现了 ``Element ``接口。
最后,由于HTML元素对DOM来说也是组成web页面或XML页面节点树中的一个节点, table元素也实现更基本的 ``Node`` 接口, ``Element`` 对象即发源于此接口。
正如下面的代码,当得到一个 table 对象的引用时,经常会轮流使用对象上的三个不同的接口函数。
~~~JavaScript
var table = document.getElementById("table");
var tableAttrs = table.attributes; // Node/Element interface
for (var i = 0; i < tableAttrs.length; i++) {
// HTMLTableElement interface: border attribute
if(tableAttrs[i].nodeName.toLowerCase() == "border")
table.border = "1";
}
// HTMLTableElement interface: summary attribute
table.summary = "note: increased border";
~~~
**DOM中核心接口**
在DOM编程时,通常使用的最多的就是 Document和 window 对象。
``window`` 对象表示浏览器中的内容,而 ``document ``对象是文档本身的根节点。``Element`` 继承了通用的 ``Node`` 接口, 将这两个接口结合后就提供了许多方法和属性可以供单个元素使用。在处理这些元素所对应的不同类型的数据时,这些元素可能会有专用的接口,如上节中的 table 对象的例子。
下面是在web和XML页面脚本中使用DOM时,一些常用的API简要列表:
- window.content
- window.onload
- window.dump()
- window.scrollTo()
- document.getElementById(id)
- document.getElementsByTagName(name)
- document.createElement(name)
- parentNode.appendChild(node)
- element.innerHTML
- element.style.left
- element.setAttribute()
- element.getAttribute()
- element.addEventListener()
## DOM与模板
在网页的一般开发流程中,我们通常会通过 `JS` 操作 `DOM` (对应 HTML 的描述产生的树),以引起界面的一些变化响应用户的行为。
例如,用户点击某个按钮的时候,`JS` 会记录一些状态到 `JS` 变量里边,同时通过 DOM API 操控 `DOM` 的属性或者行为,进而引起界面一些变化。
但是,当项目越来越大的时候,JS代码中会充斥着非常多的界面交互逻辑和程序的各种状态变量,显然这不是一个很好的开发模式,因此就有了 MVVM 的开发模式(例如 React, Vue),提倡把渲染和逻辑分离。
简单来说就是不要再让 JS 直接操控 DOM,JS 只需要管理状态即可,然后再通过一种模板语法来描述状态和界面结构的关系即可。
微信小程序的框架就用到了这个思路,如果需要把一个 `Hello World` 的字符串显示在界面上。
WXML 是这么写 :
~~~xml
<text>{{msg}}</text>
~~~
JS 只需要管理状态即可:
~~~javascript
this.setData({ msg: "Hello World" })
~~~
通过 `{{ }}` 的语法把一个变量绑定到界面上,我们称为数据绑定。仅仅通过数据绑定还不够完整的描述状态和界面的关系,还需要 `if/else`, `for`等控制能力,在小程序里边,这些控制能力都用 `wx:` 开头的属性来表达。
- WebAPP
- Linux Command
- 入门
- 处理文件
- 查找文件单词
- 环境
- 联网
- Linux
- Linux目录配置标准:FHS
- Linux文件与目录管理
- Linux账号管理与ACL权限设置
- Linux系统资源查看
- 软件包管理
- Bash
- Daemon/Systemd
- ftp
- Apache
- MySQL
- Command
- Replication
- mysqld
- remote access
- remark
- 限制
- PHP
- String
- Array
- Function
- Class
- File
- JAVA
- Protocals
- http
- mqtt
- IDE
- phpDesigner
- eclipse
- vscode
- Notepad++
- WebAPI
- Javasript
- DOM
- BOM
- Event
- Class
- Module
- Ajax
- Fetch
- Promise
- async/await
- Statements and declarations
- Function
- Framwork
- jQurey
- Types
- Promise
- BootStrap
- v4
- ThinkPHP5
- install
- 定时任务
- CodeIgniter
- React.js
- node.js
- npm
- npm-commands
- npm-folder
- package.json
- Docker and private modules
- module
- webpack.js
- install
- configuration
- package.json
- entry
- modules
- plugins
- Code Splitting
- loaders
- libs
- API
- webpack-cli
- Vue.js
- install
- Compile
- VueAPI
- vuex
- vue-router
- vue-devtools
- vue-cli
- vue-loader
- VDOM
- vue-instance
- components
- template
- Single-File Components
- props
- data
- methods
- computed
- watch
- Event-handling
- Render Func
- remark
- 案例学习
- bootstrap-vue
- modal
- fontAwesome
- Hosting Font Awesome Yourself
- using with jquery
- using with Vue.js
- HTML
- CSS
- plugins
- Chart.js
- D3.js
- phpSpreadSheet
- Guzzle
- Cmder
- Git
- git命令
- git流程
- Postman
- Markdown
- Regular Expressions
- PowerDesigner
- 附录1-学习资源