JavaScrip 之 DOM
DOM 树
HTML 文档的骨干是标签。
根据文档对象模型(DOM),每个HTML标签都是一个对象,同样标签内的文本也是一个对象。因此这些对象都可通过 JavaScript 操作
如果文档中有空格(就像任何字符一样),那么它们将成为 DOM 中的文本节点,如果我们删除它们,则不会有任何内容。
<head> 之前的空格和换行符被忽略
</body> 之后放置了一些东西,那么它会自动移动到 body 内部,因为 HTML 规范要求所有内容必须位于 <body> 内。所以 </body> 后面可能没有空格。
通常再浏览器中的文本不会显示开头/结尾的空文本节点,标签之间也不会显示空文本节点。
如果浏览器遇到格式不正确的HTML,在形成DOM是会自动修复它
如:
<html> 即使不在文档中,浏览器也会自动创建它
按DOM规范,table 必须具有 <tbody>,因此table中未使用<tbody> 形成DOM时会自动添加。
其它 节点:
注释不会以任何方式影响视觉表示,但是必须遵循一条规则 —— 如果HTML中有东西,那么它必须在DOM树中。
HTML中所有内容都是DOM的一部分,
注释是一个节点甚至<!DOCTYPE...>也是一个节
DOM总有12种节点
遍历DOM节点
所有对DOM的操作都是从document对象开始,将这个对象赋予一个变量,对其进行修改操作
最顶端的节点
DOM节点树可以通过 document属性使用
顶端的节点对应<html> 并且 <html> = document.documentElement
而<body> = document.body,<head> = document.head
docment.body可能为null,如果将script脚本放入 <head>标签种,那么此脚本无法访问到document.body,即为null
childNodes
childNodes 集合提供对所有子节点包括文本节点的访问,它看起来是一个数字,实际上只是一个可迭代的类数组对象,因此没有数组的方法
所有的Dom 集合节点都是只读的无法通过赋值来替换对应的节点
除小部分节点,几乎所有的DOM集合都是实时的,它们反应的是DOM的实时状态
不要是有 for...in来遍历DOM集合,此方法会列出其所有的属性。
注意此属性只能访问到当前script脚本之前对应的节点
可以通过elem.hasChildNodes()来检测是否含有子节点
parentNOde / siblingNode
通过elem.parentNode可访问当前节点的父节点
通过elem.previousSibling/elem.nextSibling可访问对应节点的上/下兄弟节点
只访问元素节点
- children: 只获取类型为元素节点的子节点
- firstElementChild,lastElementChild:只获取第一或最后一个子元素
- previousElementSibling, nextElementSibling:兄弟元素
- parentElement:父元素
parentElement 可能为null,因为其方法返回的是父元素节点,而parentNode返回的是任何类型的父节点,因此,document.documentElement.parentElement === null
HTMLCollection (动态)
通过元素查找子元素如果子元素是一个集合将返回 HTMLCollection 类数组
let tb = documet.querySelector('table')
let tbs = tb.tBodies // HTMLCollection [tbody]
let trs =tbs.rows // HTMLCollection [tr,tr,tr,...]
let tr1 = trs[0]
tr1.sectionRowIndex //0 当前 tr 在集合中的位置
tr1.rowIndex // 1 当前 tr 在整张表中的 位置
let tds = tr1.cells // HTMLCollection [td,td,td,...]
td[0].cellIndex //0 当前 td 在父元素 tr节点 中的位置
NodeList (静态 如果使用循环创建查询的元素,新的元素不会实时加入到NodeList中)
通过 document 中的方法 document.querySelectorAll 或elem.querySelectorAll获取的元素集合将返回NodeList类数组
getElement* 方法只能通过 document对象调用
let divs = document.querySelectorAll('div') // NodeList(4) [div.Owen, div#modal, div.main, div]
document.getElementsByTagName('div')//HTMLCollection [div.Owen]
matches
elem.matches(css)会检测 elem是否匹配到给定的css选择器,返回 true 或 false
closest
elem.closest(css)此方法会查找css选择器匹配到的祖先HTML,包括自身,并返回最先找到的元素
contains
elem.catains(dom) 判断 dom 是否为 elem 的后代,或等于elem,返回true 或false
节点属性
所有的节点都继承自根节点 EventTarget
- EventTarget:作为基础,让所有DOM 节点都支持事件
- Node:作为DOM 节点的基础,提供DOM树的核心功能:
parentNode、nextSibling、previousSibling、ChildNodes等(只能读取 getter);文本节点Text,元素节点Element,注释节点Comment都继承自Node - Element:做为DOM 元素的基类。提供元素级导航:
nextElementSibling、children、getElement*、querySelector等等,浏览器不仅支持HTML,还支持 XML、SVG等,分别对应的基类HTMLElement、XMLElement、SVGElement - HTMLElement:作为所有元素的基类,被各种元素继承
innerHTML 和 outerHTML
- innerHTML: 获取或替换当前节点的所有子节点(不包含当前节点)
- outerHTML: 替换当前节点
文档片段 DocumentFragment
用于存储节点的包装器,不会再浏览器中展示,需要通过插值方法才能展示包装器里面的内容
function creatEl(){
let frag = new DocumentFragment();
for (let i=1;i<4;i++) {
let li = document.createElement('li')
li.append(i)
frag.append(li)
}
return frag
}
ul.append(creatEl())
类样式的修改等操作
elem.className 对应元素的类名,多个类目以空格分隔
ul.className // "class1 class2 ..."
同时还要一个 elem.classList 对象可访问类名,它以类数组的方式存在,同时具有 add/remove/toggle/contains 等方法
ul.classList // DOMTokenList(2) ["333", "444", value: "333 444"]
ul.classList.add('class1')
ul.classList.remove('class1')
ul.classList.toggle('class1') // true 新增
ul.classList.toggle('class1') // false 去除
ul.classList.contains('class1') //false 是否包含
通常我们使用 style.*单独对样式属性进行修改,如果想要对多种样式进行调整可使用 cssText,此方法会直接替换之前的样式
ul.style.cssText = `
color: red ;
background-color: skyblue;
width: 20px;
text-align: center;`
style 属性仅针对 style 属性值进行操作,无法读取css类中的属性值
<style>
body {margin:20 auto;}
</style>
<script>
document.body.style.margin // ""
</script>
这时我们需要使用 getComputedStyle(el,[,pseudo])方法来获取对应的值
如果不传参或值无意义,将返回元素所有样式,其属性值都为解析值,如 font-size:1em 最后获取的可能为解析后的值"16px"
let res = getComputedStyle(document.body)
res.marginTop // "20px"
res.margin // 谷歌 "20px 0px" 在火狐中为 "" 因此访问确切属性值须使用完整属性名
获取元素的尺寸和滚动距离
- offsetTop/Left: 获取相对于设置有position属性为 absolute relative、fixed 的值或td、th、table、body的元素的距离
- offsetWidth/Height:获取外部宽度/高度,包含border,padding,scrollbar (display:none 或自身不在文档中,其值为0或null,由此可判断当前元素是否被隐藏)
- clientTop/Left:获取内侧与外侧的距离(滚动条在左边时,包含滚动条的宽度)
- clientWidth/Height:获取可视区内容的宽高,即不包含滚动条和border
- scrollWidth/Height:获取全部内容(包含隐藏部分)的宽高
- scrollTop/Left: 获取 元素隐藏部分的上/左距离,包含border,这两个属性可修改,其它属性能只读取
HTML 文件里如果没有 <!DOCTYPE HTML> 上述的属性可能会有所不同,这不是一个 JavaScript 的问题,但会影响到 JavaScript。
滚动浏览器窗口
pageXOffset/pageYOffset: 获取可视窗口移动的距离 无法设值
可通过 window.scrollBy, window.scrollTo, elem.scrollIntoView来滚动窗口
scrollBy(x,y):滚动页面至相对于现在位置的(x,y)位置scrollTo(x,y):滚动到页面相对于文档左上方的(x,y),位置,类似于scrollTop/scrollLeftelem.scrollIntoView(truly):如果 truly 为真则使 当前元素 滚动至窗口顶部,元素顶部与窗口顶部对齐,如果truly 为false,则当前元素底部与窗口底部对齐。
如果禁止窗口滚动可使 样式属性 overflow 值为 hidden
坐标
getBoundingClientRect()`方法获取相对于可视窗口的坐标对象
其所有属性都是以可视窗口左端(X)和顶部(Y)为起点
ul.getBoundingClientRect()
/*
DOMRect {
bottom: 829.59375 // 元素底部的Y坐标
height: 210 // 元素真实高度
left: 0 // 元素左边 X 坐标
right: 1903 // 元素右边 X 坐标
top: 619.59375 // 元素顶部 Y 坐标
width: 1903 // 元素自身真实宽度即不包含滚动条
x: 0
y: 619.59375
}
*/
document.elementFromPoint
document.elementFromPoint(x,y)返回可视窗口坐标(x,y),最顶层的元素
let elem = document.elementFromPoint(0,0) // <p>556666</p>
如果x,y不在正常范围内将返回 null,
相对于文档坐标,JS并未提供原生标准方法,可自己写一个出来:
function getDomCoords(el){
let {top,left} = el.getBoundingClientRect()
return {
top:top+ window.pageYOffset,
left:left+window.pageXOffest
}
}
JavaScrip 之 DOM的更多相关文章
- JavaScrip的DOM操作
1.DOM的基本概念 DOM是文档对象模型,这种模型为树模型,文档是指标签文档:对象是指文档中每个元素:模型是指抽象化的东西 2.Windows对象操作 一.属性和方法 二.Window.open(& ...
- JavaScrip的DOM操作(13号讲)
1.DOM的基本概念 DOM是文档对象模型,这种模型为树模型,文档是指标签文档:对象是指文档中每个元素:模型是指抽象化的东西 2.Windows对象操作 一.属性和方法 二.Window.open(& ...
- JavaScrip_12.23
笔记系列,零散的知识点,准备以后复习整理使用 JavaScrip - 事件DOM绑定[将函数添加到一个元素对象的属性中] 1.事件 鼠标.键盘.操作等:所有的GUI都有 onclick(单击事件) 例 ...
- JavaScrip之BOM、DOM
BOM 浏览器对象模型(BrowserObjectModel),可以对浏览器窗口进行访问和操作.使用 BOM,开发者可以移动窗口.改变状态栏中的文本以及执行其他与页面内容不直接相关的动作. 使 Jav ...
- 操作DOM -------JavaScrip
本文摘要:http://www.liaoxuefeng.com/ 经常用到. 由于HTML文档被浏览器解析后就是一棵DOM树,要改变HTML的结构,就需要通过JavaScript来操作DOM. 始终记 ...
- Javascrip动态添加样式,Dom操作,获取自定义属性
var layer=document.querySelector('.layer') 添加样式: 添加单个样式: layer.style.display="block" 添加多个样 ...
- JavaScrip——DOM操作(属性操作)
Attribute a.setAttribute("属性名","属性值")——设置属性 a.getSttribute("属性名")——获取属 ...
- JavaScrip——DOM操作(查找HTML元素/修改元素)
innerHTML 1.查找元素——document.getElementById("intro") 2.输出查找的结果: (1)var a=document.getElement ...
- JavaScript高级程序设计学习笔记--DOM
DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序接口). Document类型 文档的子节点 虽然DOM标准规定Document节点的子节点可以是DocumentType,Ele ...
随机推荐
- 使用 Flask 和 Vue.js 来构建全栈单页应用
在这个教程中,我将向你展示如何将 Vue 的单页面应用和 Flask 后端连接起来. 简单的来说,如果想在 Flask 中使用 Vue 框架是没有什么问题的. 但在实际中存在一个明显的问题就是 Fla ...
- 《Windows内核安全与驱动开发》4.1 文件操作
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发>4.1 文件操作 从 C:\a.txt 中读取一部分内容并利用 DbgPrin ...
- ThinkPHP5——模型关联(一对一关联)
定义 定义一对一关联使用了hasOne,hasOne方法的参数包括: hasOne('关联模型名','外键名','主键名',['模型别名定义'],'join类型'); 下面定义一个用户表,公司给每个用 ...
- 人人学IoT 助学思维导图
原来学IoT记录的学习笔记,学完之后,对考试和工作都有些帮助,特分享给大家 笔记分享链接 https://share.mindmanager.com/#publish/s6TqusKeSG6aflXL ...
- 挑战10个最难的Java面试题(附答案)【上】【华为云技术分享】
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/devcloud/article/deta ...
- 从“职场小白”进阶为“行业大牛”,四个"锦囊"教你破局
在早期软件行业,会存在一个普遍的现象,有些大学的本科,或者研究生毕业,他们去面试工作的时候会发现,面试下来代码能力可能不是太好,这种情况下公司会问你愿不愿意去做测试? 如果说早期软件测试行业还是一个风 ...
- 为什么查询出来的数据保存到Arraylist?插入删除数据为啥用LinkedList?
引言:这是我在回答集合体系时,被问到的一个问题,也是因为没有深入学习所以回答的并不是很好,所以这两天看了一下,以下是我的一些回答与学习方法. 学习方法:我们学习,系统性的学习肯定是比零散的学习更有效的 ...
- 学习之Redis(一)
一.redis简介 一般学习,最好先去官网,之所以建议看官网,是因为这是一手的学习资料,其他资料都最多只能算二手,一手资料意味着最权威,准确性最高.https://redis.io/topics/in ...
- go学习第三天、数据类型
基本数据类型 bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr byte // alias ...
- Pandas里面常用的一些数据分析函数总结
import pandas as pdimport numpy as np pandas 有两个主要的数据结构:Series 和 DataFrame:Series 是一个一维数组对象 ,它包含一组索引 ...