DOM概念
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口。在网页上,组织页面(或文档)的对象被组织在一个树形结构中,用来表示文档中对象的标准模型就称为DOM。
**注意:**IE中的多有DOM对象都是以COM对象的形式实现的。
文档:把一个html文件看成是一个文档,由于万物皆对象,所有把这个文档看成是一个对象。
html:展示信息,展示数据的。
xml:侧重于存储数据。
元素element:页面中的所有的标签都是元素,元素都可以看成是对象。
节点node:页面中所有的内容都是节点:标签,属性,文本。
DOM又称为文档树模型
技巧
- 如果是循环的方式添加事件,推荐用命名函数。
- 如果不是循环的方式添加事件,推荐使用匿名函数。
btn.onclick = function() {
}
- return false可以阻止a跳转
- 在表单中value和innerText都可修改文本内容。推荐第一种。
事件
事件:触发-响应机制
Event接口表示在DOM中发生的任何事件,一些是用户生成的(例如鼠标或键盘事件),而其他由API生成。
事件三要素
- 事件源:触发(被)事件的元素
- 事件类型:事件的触发方式(例如鼠标点击或键盘点击)
- 事件处理程序:事件触发后要执行的代码(函数形式)
节点层次
Node类型
除了IE之外,在其他所有浏览器中都可以访问到这个类型。JavaScript中的所有节点类型都是继承自Node类型,因此所有节点类型都共享着相同的基本属性和方法。
每个节点都有一个nodeType属性,用于表明节点的类型。
- Node.ELEMENT_NODE(1)
- Node.ATTRIBUTE_NODE(2)
- Node.TEXT_NODE(3)
- Node.CDATA_SECTION_NODE(4)
- Node.ENTITY_REFERENCE_NODE(5)
- Node.ENTITY_NODE(6)
- Node.PROCESSING_INSTRUCTION_NODE(7)
- Node.COMMENT_NODE(8)
- Node.DOCUMENT_NODE(9)
- Node.DOCUMNET_TYPE_NODE(10)
- Node.DOCUMENT_FRAGMENT_NODE(11)
- Node.DOCUMENT_NOTATION_NODE(12)
**PS:**为确保跨浏览器兼容,最好还是讲nodeType属性与数字值进行比较。
nodeName和nodeValue属性
对于元素节点,nodeName中保存的始终都是元素的标签名,而nodeValue的值则始终是null。
标签节点的nodeValue为null,属性节点的nodeValue为属性值,文本节点的nodeValue为文本内容。
节点关系
- childNodes属性:返回一个NodeList对象,是一种类数组对象,保存着节点的所有子节点集合。
- parentNode属性:返回指定节点的父节点
- previousSibling属性:返回同级的前一个节点
- nextSibling属性:返回同级的后一个节点
- firstChild属性:返回指定节点的子节点中的第一个
- lastChild属性:返回指定节点的子节点中的最后一个
- **hasChildNodes()**方法:查询该节点是否有子节点,有则true,反之false
- ownerDocument属性:返回整个文档的文档对象
操作节点(重点)
- **appendChild()**方法:在指定节点的childNodes列表的末尾添加一个节点。
注意:如果传入到appendChild()中的节点已经是文档的一部分,那结果就是将该节点从原来位置转移到新位置。 - **insertBefore()**方法:在某个节点前插入。
接受两个参数:要插入的节点和作为参照的节点。
注意:如果参照节点是null,则insertBefore()与appendChild()执行相同的操作。 - **replaceChild()**方法:将指点节点替换为新节点。
接受两个参数:要插入的节点和要替换的节点。 - **removeChild()**方法:移除节点。
注意:替换的节点和移除的节点依旧在文档中,只是没有自己位置了。
其他方法
- **cloneNode()**方法:用于创建调用这个方法的节点的一个完全相同的副本。
接受一个布尔值参数:true为执行深复制,即复制节点及其整改子节点数;false为执行浅复制,即只复制节点本身。
注意:复制节点不会复制JavaScript属性,建议在复制之前先一次节点的事件处理程序。 - **normalize()**方法:处理调用者的文档树中的文本节点。移除空的文本节点,并合并相邻的文本节点为一个文本节点。
Document类型
Document类型表示文档,在浏览器中document对象是一个实例,表示整个HTML页面。nodeType为9。
文档的子节点
- documentElement属性,该属性始终指向HTML页面的元素。
document.documentElement
- body属性,直接指向元素.
document.body
- doctype属性:获取文档类型。(少用)
document.doctype
文档信息
- title属性:包含
元素中的文本,也可用于修改。
document.title
- URL属性:包含页面完整的URL(地址栏显示的)。
document.URL
- domain属性:包含页面的域名。
document.domain
- referrer属性:保存着链接到当前页面的那个页面的URL,如果没有来源网页则为空字符串。
document.referrer
查找元素
根据id获取元素(掌握)
document.getElementById(“id属性的值”)
var div = document.getElementById('main');
console.log(div);
// 获取到的数据类型 HTMLDivElement,对象都是有类型的
// HTMLDivElement <-- HTMLElement <-- Element <-- Node <-- EventTarget
注意:由于id名具有唯一性,部分浏览器支持直接使用id名访问元素,但不是标准方式,不推荐使用。
根据标签名获取元素(掌握)
document.getElementsByTagName(“标签名字”),返回的是一个伪数组。
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
var div = divs[i];
console.log(div);
}
根据name获取元素(了解)
document.getElementsByName(“name属性的值”),返回的是一个伪数组。
var inputs = document.getElementsByName('hobby');
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
console.log(input);
}
根据类名获取元素(了解)
document.getElementsByClassName(“类名”),返回的是一个伪数组。
var mains = document.getElementsByClassName('main');
for (var i = 0; i < mains.length; i++) {
var main = mains[i];
console.log(main);
}
根据选择器获取元素(了解)
document.querySelector(“选择器的名字”)
document.querySelectorAll(“选择器的名字”);,返回的是一个伪数组。
var text = document.querySelector('#text');
console.log(text);
var boxes = document.querySelectorAll('.box');
for (var i = 0; i < boxes.length; i++) {
var box = boxes[i];
console.log(box);
}
特殊集合
- document.anchors 包含文档中所有带name特性的元素。
- document.forms 包含文档中所有的元素。
- documentimages 包含文档中所有的
元素。
- document.links 包含文档中所有带href特性的元素。
文档写入
- write()和writeln()接受一个字符串参数,即要写入到输出流中的文本。
- open()和close()分别用于打开和关闭网页的输出流。
Element类型
noteType的值为1。
可以在任何浏览器中通过脚本访问Element类型的构造函数及类型。
HTML元素(常用)
在js中设置或读取标签属性:对象元素.属性名
注意:设置或读取某元素的样式类,用的时className,非class。
取得特性(不常用,多只用于自定义属性)
元素对象.getAttribute(“属性名”);
一般只用于取自定义特性,但需在自定义特性名前加“data-”。
设置特性(不常用,多只用于自定义属性)
元素对象.setAttribute(“属性名”,“值”);
清除特性(不常用)
元素对象.removeAttribute(“属性名”);
创建元素(常用)
**document.createElement()**可以创建新元素,接受一个参数,即要创建元素的标签名,同时也可以包含属性,但注意转义“\”。
Text类型(纯文本内容)
创建文本节点
**document.createTextNode()**创建新文本节点,接受一个插入节点中的文本参数。
分割文本节点(常用提取信息)
**splitText()**将一个文本节点分成两个文本节点,即按照指定的位置分割nodeValue值,返回一个新文本节点。接受一个位置参数。
var element = document.createElement("div");
element.className = "message";
var textNode = document.cteateTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
var newNode = element.firstChild.splitText(5);
console.log(element.firstChild.nodeValue); //"Hello"
console.log(newNode.nodeValue); //" world!"
属性操作
非表单元素的属性
元素对象.属性名
href、title、id、src、className
var link = document.getElementById('link');
console.log(link.href);
console.log(link.title);
var pic = document.getElementById('pic');
console.log(pic.src);
- innerHTML和innerText
使用innerText主要设置文本的,若含有设置标签,则标签没有效果。
innerHTML可设置文本内容,也可包含HTML标签,有效果。
var box = document.getElementById('box');
box.innerHTML = '我是文本<p>我会生成为标签</p>';
console.log(box.innerHTML);
box.innerText = '我是文本<p>我不会生成为标签</p>';
console.log(box.innerText);
- HTML转义符
" "
‘ '
& &
< < //less than 小于
> > // greater than 大于
空格
© ©
- innerText的兼容性处理
如果这个属性在浏览器中不支持,那么这个类型是underfined。(可用于写兼用代码)
function setInnerText(element, text) {
if (typeof element.textContent == "undefined") {
element.innerText = text;
} else {
element.textContent = text;
}
}
function getInnerText(element) {
if (typeof element.textContent == "undefined") {
return element.innerText;
} else {
return element.textContent;
}
}
表单元素属性
- value 用于大部分表单元素的内容获取(option除外)
- type 可以获取input标签的类型(输入框或复选框等)
- disabled 禁用属性
- readonly只读属性
- checked 复选框选中属性
- selected 下拉菜单选中属性
样式操作
- 使用style方式设置的样式显示在标签行内
元素对象.style.属性名
var box = document.getElementById('box');
box.style.width = '100px';
box.style.height = '100px';
box.style.backgroundColor = 'red';
- 注意
通过样式属性设置宽高、位置的属性类型是字符串,需要加上px。 - 凡是CSS中这个属性是多个单词的写法,在js代码中DOM操作的时候,把-干掉,后面的单词的首字母大写。
类名操作
- 修改标签的className属性相当于直接修改标签的类名
元素对象.className = "样式类名"
var box = document.getElementById('box');
box.className = 'clearfix';
创建元素的三种方式
document.write()
创建元素,如果是在页面加载完毕后,此时通过这种方式创建元素,那么页面上存在的所有的内容全部被干掉。
document.write('新设置的内容<p>标签也可以生成</p>');
innerHTML
如果直接在body创建,效果与document.write()一样的把页面所有内容干掉,如果添加某容器内就不会出现这问题
var box = document.getElementById('box');
box.innerHTML = '新内容<p>新标签</p>';
document.createElement()
var div = document.createElement('div');
document.body.appendChild(div);
事件详解
常用事件
方法 | 描述 |
---|---|
onclick | 鼠标点击事件 |
onmouseover | 光标移入到某元素之上 |
onmouseout | 光标从某元素移出 |
onmousedown | 光标按钮被按下 |
onfocus | 获取焦点时触发 |
onblur | 失去焦点时触发 |
onload | 自动加载 |
onkeyup | 键盘弹起 |
onkeydown | 键盘按下 |
oninput | 当指定内容发生变化时触发(复制粘贴也触发) |
oninvalid | 当正则表达式验证不通过时触发,this.setCustomValidty(“信息”);设置默认提示信息。 |
注册/移除事件的三种方式(重点)
注意用什么方式绑定事件,就用什么方式解绑。
为同一个元素重复添加同一事件类型会覆盖上面的方法。
- 对象.on事件类型 = 处理函数;
- 对象.on事件类型 = null;
为同一个元素绑定多个相同的事件,同类型包含覆盖。 - 对象.addEventListener(不带on的事件类型, 处理函数, 控制事件阶段布尔类型);(IE8不支持)
- 对象.attachEvent(带on的事件类型, 处理函数);(谷歌、火狐不支持)
对应下列解绑方法,但处理函数要是对应命名函数。 - 对象.removeEventListener(不带on的事件类型, 函数名字,控制事件阶段布尔类型)
- 对象.detachEvent(带on的事件类型, 函数名字)
var box = document.getElementById('box');
box.onclick = function () {
console.log('点击后执行');
};
box.onclick = null;
box.addEventListener('click', eventCode, false);
box.removeEventListener('click', eventCode, false);
box.attachEvent('onclick', eventCode);
box.detachEvent('onclick', eventCode);
function eventCode() {
console.log('点击后执行');
}
兼容代码
function addEventListener(element, type, fn) {
if (element.addEventListener) {
element.addEventListener(type, fn, false);
} else if (element.attachEvent){
element.attachEvent('on' + type,fn);
} else {
element['on'+type] = fn;
}
}
function removeEventListener(element, type, fn) {
if (element.removeEventListener) {
element.removeEventListener(type, fn, false);
} else if (element.detachEvent) {
element.detachEvent('on' + type, fn);
} else {
element['on'+type] = null;
}
}
事件对象
JavaScript在时间处理函数中默认传递了event对象,也就是事件对象。
即:
function 名字() {
}
等价于
function 名字(e) {
}
PS:为了兼容,写上e = e|| window.event;
event对象常用的属性
属性 | 描述 |
---|---|
type | 获取这个事件的事件类型 |
target | 获取绑定事件的DOM元素 |
data | 获取事件调用时春如的额外参数 |
relatedTarget | 对鼠标事件,标示触发事件时离开或进入的DOM元素 |
currentTarget | 冒泡前的当前触发事件的DOM对象,等同于this |
pageX/pageY | 鼠标事件中,事件相对页面原点的水平/垂直坐标 |
result | 上一个事件处理函数返回的值 |
timeStamp | 事件发生时的时间 |
which | 获取鼠标的左、中、右键(1,2,3),或获取键盘按键 |
eventPhase | 返回处于哪个阶段 |
**event.stopPropagation();**阻止冒泡行为
**event.preventDefault();**阻止默认行为
事件的三个阶段
- 捕获阶段(由外向里)
- 当前目标阶段
- 冒泡阶段(由里向外)
事件对象.eventPhase属性可以查看事件触发时所处的阶段
IE的事件对象是window.event;谷歌和火狐事件对象是event。
事件冒泡(注意点)
多个元素嵌套,有层次关系,这些元素都注册了相同的事件,如果里面的元素的事件触发了,外面的元素的事件自动触发。(要阻止发生)
window.event.cancelBubble = true;(谷歌、IE支持,火狐不支持)
event.stopPropagation();(谷歌、火狐支持,IE不支持)
表格对象
属性/方法 | 描述 | |
---|---|---|
rows[] | 返回包含表格中所有行的一个数组 | |
inserRow(index) | 在表格中插入一个新行 | |
deleteRow(index) | 从表格中删除一行 | |
cells[] | 返回包含行中所有单元格的一个数组 | |
rowIndex | 返回该行在表中的位置 | |
insertCell(index) | 在一行中的指定位置插入一个空的 | 标签 |
deleteCell(index) | 删除行中指定的单元格 | |
cellIndex | 返回单元格在某行单元格集合中的位置 | |
innerHtml | 设置或返回单元格的开始标签和结束标签之间的HTML | |
align | 设置或返回单元格内部数据的水平排列方式 | |
className | 设置或返回元素的class属性 |
PS:表格中的rowIndex是从0开始;rows.length可查多少行
扩展
一次创建多节点
document对象的createDocumentFragment()创建DOM文档碎片对象,可把多个节点添加到碎片上,再一次性添加到页面。createTextNode()。
取内部样式表或外部样式表中的属性值(注意)
通过style只能获取内联样式的属性值,因此使用
-
元素.currentStyle.属性;(只局限于IE)
-
**document.defaultView.getComputedStyle(元素,null).属性;**两个参数:获取样式元素和伪元素。
兼容代码
function getStyle(element,attr) {
//判断浏览器是否支持这个方法
return window.getComputedStyle? window.getComputedStyle(element,null)[attr]:element.currentStyle[attr];
}
特效
偏移量(offset系列)
- offsetWidth、offsetHeight获取宽和高
- offsetTop/Left/Right/Bottom获取距离顶部/左部/右部/底部的距离
注意:不脱标时候与父margin+父padding+父border+自己margin;脱标后只与left…和自己的margin有关。 - offsetParent用于获取定位的父级元素
- offsetParent和parentNode的区别
var box = document.getElementById('box');
console.log(box.offsetParent);
console.log(box.offsetLeft);
console.log(box.offsetTop);
console.log(box.offsetWidth);
console.log(box.offsetHeight);
页面事件(scroll系列)(重点)
- scrollWidth、scrollHeight内容实际宽、高,不包含边框。
- scrollLeft、scrollTop设置或获取位于对象左边界/最顶端和窗口中可见内容的最顶端之间的距离。
兼容代码
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
客户区大小(client系列)可视区域
- clientWidth、clientHeight元素可视区域的宽、高(不包含边框)。
- clientLeft/Top左边框/上边框的宽度。
- clientX、clientY可视区域鼠标的x、y坐标。
附
pageX相对左部页面边界的x坐标。(IE8不支持)
pageY相对顶部页面边界的Y坐标。