基本介绍
获取节点
操作节点
创建节点
document.createElement(tag)
用给定的标签创建一个新 元素节点(element node):
let div = document.createElement('div');
document.createTextNode(text)
用给定的文本创建一个 文本节点:
let textNode = document.createTextNode('Here I am');
插入.删除.替换节点
一.
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
node.remove() — 移除 node
文本字符串被“作为文本”插入
二.
parent.appendChild(node)
parent.insertBefore(node, nextSibling)
parent.removeChild(node)
parent.replaceChild(newElem, node)
这些方法都返回 node
克隆节点
cloneNode
调用 elem.cloneNode(true) 来创建元素的一个“深”克隆 — 具有所有特性(attribute)和子元素。如果我们调用 elem.cloneNode(false) ,那克隆就不包括
子元素。
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<div class="alert" id="div">
<strong>Hi there!</strong> You've read an important message.
DocumentFragment 是一个特殊的 DOM 节点,用作来传递节点列表的包装器
(wrapper)。
我们可以向其附加其他节点,但是当我们将其插入某个位置时,则会插入其内容。
例如,下面这段代码中的 getListContent 会生成带有 <li> 列表项的片段,然后
将其插入到 <ul> 中:
请注意,在最后一行 (*) 我们附加了 DocumentFragment ,但是它和 ul “融为一
体(blends in)”了,所以最终的文档结构应该是:
DocumentFragment 很少被显式使用。如果可以改为返回一个节点数组,那为什么
还要附加到特殊类型的节点上呢?重写示例:
</div>
<script>
let div2 = div.cloneNode(true); // 克隆消息
div2.querySelector('strong').innerHTML = 'Bye there!'; // 修改克隆
div.after(div2); // 在已有的 div 后显示克隆
</script>
节点属性
nodeType
我们可以使用它来查看节点是文本节点还是元素节点。它具有一个数值型值(numeric value): 1 表示元素, 3 表示文本节点,其他一些则代表其他节点类型。只读。
nodeName/tagName
用于元素名,标签名(除了 XML 模式,都要大写)。对于非元素节点, nodeName 描 述了它是什么。只读。
alert( document.body.nodeName ); // BODY
alert( document.body.tagName ); // BODY
差别:
tagName 属性仅适用于 Element 节点。
nodeName 是为任意 Node 定义的:
对于元素,它的意义与 tagName 相同。
对于其他节点类型(text,comment 等),它拥有一个对应节点类型的字符串
innerHTML
元素的 HTML 内容。可以被修改。
<body>
<p>A paragraph</p>
<div>A div</div>
<script>
alert( document.body.innerHTML ); // 读取当前内容
document.body.innerHTML = 'The new BODY!'; // 替换它
</script>
</body>
我们可以尝试插入无效的 HTML,浏览器会修复我们的错误:
<body>
<script>
document.body.innerHTML = '<b>test'; // 忘记闭合标签
alert( document.body.innerHTML ); // <b>test</b>(被修复了)
</script>
</body>
innerHTML+= 做了以下工作:
- 移除旧的内容。
- 然后写入新的 innerHTML (新旧结合)。
相同效果:
elem.innerHTML += "...";
// 进行写入的一种更简短的方式:
elem.innerHTML = elem.innerHTML + "..."
innerText
与innerHTNL不同,只获取文本
outerHTML
元素的完整 HTML。对 elem.outerHTML 的写入操作不会触及 elem 本身。而是在 外部上下文中将其替换为新的 HTML。
<div id="elem">Hello <b>World</b></div>
<script>
alert(elem.outerHTML); // <div id="elem">Hello <b>World</b></div>
</script>
注意:与innerHTML不同,写入outerHTML不会改变元素,而是在DOM 中替换它。
<div>Hello, world!</div>
<script>
let div = document.querySelector('div');
// 使用 <p>...</p> 替换 div.outerHTML
div.outerHTML = '<p>A new element</p>'; // (*)
// 蛤!'div' 还是原来那样!
alert(div.outerHTML); // <div>Hello, world!</div> (**)
</script>
nodeValue/data
非元素节点(文本、注释)的内容。两者几乎一样,我们通常使用 data 可以被修改。
读取文本节点和注释节点的内容的示例:
<body>
Hello
<!-- Comment -->
<script>
let text = document.body.firstChild;
alert(text.data); // Hello
let comment = text.nextSibling;
alert(comment.data); // Comment
</script>
</body>
textContent
元素内的文本:HTML 减去所有 <tags> 。写入文本会将文本放入元素内,所有特殊 字符和标签均被视为文本。可以安全地插入用户生成的文本,并防止不必要的 HTML 插入。
<div id="news">
<h1>Headline!</h1>
<p>Martians attack people!</p>
</div>
<script>
// Headline! Martians attack people!
alert(news.textContent);
</script>
假设我们有一个用户输入的任意字符串,我们希望将其显示出来。
使用 innerHTML ,我们将其“作为 HTML”插入,带有所有 HTML 标签。
使用 textContent ,我们将其“作为文本”插入,所有符号(symbol)均按字面意
义处理。
hidden
当被设置为 true 时,执行与 CSS display:none 相同的事。
<div>Both divs below are hidden</div>
<div hidden>With the attribute "hidden"</div>
<div id="elem">JavaScript assigned the property "hidden"</div>
<script>
elem.hidden = true;
</script>
操作
一.
elem.hasAttribute(name) — 检查是否存在这个特性。
elem.getAttribute(name) — 获取这个特性值。
elem.setAttribute(name, value) — 设置这个特性值。
elem.removeAttribute(name) — 移除这个特性。
elem.attributes — 所有特性的集合。
<body>
<div id="elem" about="Elephant"></div>
<script>
alert( elem.getAttribute('About') ); // (1) 'Elephant',读取
elem.setAttribute('Test', 123); // (2) 写入
alert( elem.outerHTML ); // (3) 查看特性是否在 HTML 中(在)
for (let attr of elem.attributes) { // (4) 列出所有
alert( `${attr.name} = ${attr.value}` );
}
</script>
</body>
二.
样式
一·
二.
类
className
className — 字符串值,可以很好地管理整个类的集合。
classList
具有 add/remove/toggle/contains 方法的对象,可以很好
地支持单个类。
方法:
elem.classList.add/remove(class) — 添加/移除类。
elem.classList.toggle(class) — 如果类不存在就添加类,存在就移除
它。
elem.classList.contains(class) — 检查给定类,返回 true/false 。
获取元素节点
getElementById
getElementsByName(name)
返回在文档范围内具有给定 name 特性的元素
getElementsByClassName(className)
返回具有给定CSS类的元素。
getElementsByTagName(tag)
查找具有给定标签的元素,并返回它们的集合。 tag 参数也可以是对于“任何标签”的星号 "*"
// 获取文档中的所有 div
let divs = document.getElementsByTagName('div');
querySelectorAll
返回元素中与给定 CSS 选择器匹配的所有元素。
<ul>
<li>The</li>
<li>test</li>
</ul>
<ul>
<li>has</li>
<li>passed</li>
</ul>
<script>
let elements = document.querySelectorAll('ul > li:last-child');
for (let elem of elements) {
alert(elem.innerHTML); // "test", "passed"
</script>
querySelector
调用会返回给定 CSS 选择器的第一个元素
matches
检查元素是否与给定的 CSS 选择器匹配。它返回 true 或 false 。
closest
元素的祖先(ancestor)是:父级,父级的父级,它的父级等。祖先们一起组成了从元
素到顶端的父级链。
查找与 CSS 选择器匹配的最近的祖先。 元素自己也会被搜索。
方法 closest 在元素中得到了提升,并检查每个父级。如果它与选择器
匹配,则停止搜索并返回该祖先。
h1>Contents</h1>
<div class="contents">
<ul class="book">
<li class="chapter">Chapter 1</li>
<li class="chapter">Chapter 1</li>
</ul>
</div>
<script>
let chapter = document.querySelector('.chapter'); // LI
alert(chapter.closest('.book')); // UL
alert(chapter.closest('.contents')); // DIV
alert(chapter.closest('h1')); // null(因为 h1 不是祖先)
</script>
注意
所有的 "getElementsBy*" 方法都会返回一个 实时的(live) 集合。这样的集合始终反映的是文档的当前状态,并且在文档发生更改时会“自动更新”。
<div>First div</div>
<script>
let divs = document.getElementsByTagName('div');
alert(divs.length); // 1
</script>
<div>Second div</div>
<script>
alert(divs.length); // 2
</script>
querySelectorAll 返回的是一个 静态的 集合。就像元素的固定数组。 如果我们使用它,那么两个脚本都会输出 1 :
<div>First div</div>
<script>
let divs = document.querySelectorAll('div');
alert(divs.length); // 1
</script>
<div>Second div</div>
<script>
alert(divs.length); // 1
</script>
获取元素尺寸
注意:
获取元素的偏移量
参考点:定位父级
如果父级元素没有定位,偏移量相当于body
参考点:自身(相当于边框)
获取可视窗口的尺寸
事件
基本
事件解绑
事件类型
鼠标事件
click —— 当鼠标点击一个元素时(触摸屏设备会在点击时生成)
dbclick —— 双击执行
contextmenu —— 当鼠标右键点击一个元素时
mouseover / mouseout —— 当鼠标指针移入/离开一个元素时
mousedown / mouseup —— 当在元素上按下/释放鼠标按钮时
mousemove —— 当鼠标移动时
键盘事件
keydown 和 keyup —— 当按下和松开一个按键时
表单(form)元素事件
submit —— 当访问者提交了一个 <form> 时
focus —— 当访问者聚焦于一个元素时,例如聚焦于一个<input>
触摸事件
Document事件
DOMContentLoaded —— 当 HTML 的加载和处理均完成,DOM 被完全构建完成 时
CSS 事件
transitionend —— 当一个 CSS 动画完成时
事件对象
基本介绍
鼠标事件
- 相对于窗口的坐标: clientX 和 clientY
- 相对于文档的坐标: pageX 和 pageY
- 相对于触发元素的坐标:offsetX 和 offsetY
例如,如果我们有一个大小为 500x500 的窗口,并且鼠标在左上角,那么 clientX 和 clientY 均为 0 ,无论页面如何滚动。
如果鼠标位于中间,那么 clientX 和 clientY 均为 250 。这与它在文档中的位置 无关。在这方面,它们类似于 position:fixed 。