一些定义和说明
- 节点及其类型:
1). 元素节点:html标签
2). 属性节点: 元素的属性, 可以直接通过属性的方式来操作.
3). 文本节点: 是元素节点的子节点, 其内容为文本.
在 html 文档的什么位置编写 js 代码?
- 直接在 html 页面中书写代码.
Click Me!
缺点:
①. js 和 html 强耦合, 不利用代码的维护
②. 若 click 相应函数是比较复杂的, 则需要先定义一个函数, 然后再在 onclick 属性中完成对函数的引用, 比较麻烦 - . 一般地, 不能在 body 节点之前来直接获取 body 内的节点, 因为此时 html 文档树还没有加载完成,
获取不到指定的节点:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Untitled Document</title>
<script type="text/javascript">
var cityNode = document.getElementById("city");
//打印结果为 null.
alert(cityNode);
</script>
</head>
<body>
- . 可以在整个 html 文档的最后编写类似代码, 但这不符合习惯
- . 一般地, 在 body 节点之前编写 js 代码, 但需要利用 window.onload 事件,
该事件在当前文档完全加载之后被触发, 所以其中的代码可以获取到当前文档的任何节点.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Untitled Document</title>
<script type="text/javascript">
window.onload = function () {
var cityNode = document.getElementById("city");
alert(cityNode);
};
</script>
</head>
<body>
获取标签(元素)节点:
-
document.getElementById
: 根据 id 属性获取对应的单个节点 -
document.getElementsByTagName
: 根据标签名获取指定节点名字的数组, 数组对象 length 属性可以获取数组的长度 -
document.getElementsByName
: 根据节点的 name 属性获取符合条件的节点伪数组, 但 ie 的实现方式和 W3C 标准有差别: 在 html 文档中若某节点(li)没有 name 属性, 则 ie 使用 getElementsByName 不能获取到节点数组, 但火狐可以. -
document.getElementsByClassName
:根据节点的类名获取标签的伪数组 ,ie8不支持,他是h5标准 -
document.querySelector("#id名")
:获取指定id的标签节点 -
document.querySelectorAll(".类名")
:获取指定选择器的节点
节点(Node)
1.节点的属性:
(1)nodeName: 代表当前节点的名字,只读属性.,如果给定节点是一个文本节点, nodeName 属性将返回内容为 #text 的字符串
(2)nodeType:返回一个整数, 这个数值代表着给定节点的类型. 只读属性. 1 -- 元素节点, 2 -- 属性节点, 3 -- 文本节点3)
(3)nodeValue:返回给定节点的当前值(字符串). 可读写的属性
2. 获取节点
(1)获取节点的父节点:dom对象.parentNode
//可联级获取dom对象.parentNode.parentNode
上帝节点为document。
(2)获取节点的父元素:dom对象.parentElement
(3)获取子结点:dom对象.childNodes
// 获取当前对象的所有子结点
(4)获取子元素:dom对象.children
(5)获取标签/元素的属性结点:dom对象.getAttributeNode("属性名")
(6)获取第一个子节点:dom对象.firstChild
(7)获取第一个子元素:dom对象.firstElementChild
(8)获取最后一个子节点:dom对象.lastChild
(9)获取最后一个子元素:dom对象.ElementChild
(10)获取前一个兄弟节点:dom对象.previousSibling
(11)获取的前一个兄弟元素:dom对象.previousElementSibling;
(12)获取的后一个兄弟节点:dom对象.nextSibling;
(13)获取的后一个兄弟元素:dom对象.nextElementSibling;
注意:[6 - 13]这段代码在IE8中有兼容性问题: 在元素标签与元素标签之间没有文本的前提下,凡是获取节点的,都变成了获取元素,凡是获取元素的,都不支持(undefined)
3. 创建结点:
(1)document.write(“html文档”); //事件调用会出现覆盖,正常页面加载不覆盖。
(2)dom对象.innerHTML= "html文档“; //如果dom对象有子标签,则会被覆盖。如果要追加可以innerHTML += "追加的html文档";
(3)createElement(“标签名称”): 新元素节点不会自动添加到文档里,需要配合父dom对象.appendChild(“新建的元素对象”)
方式追加到父dom对象的子元素末尾。
- 为元素节点添加子节点配合createElement(“标签名称”)使用:
(1)dom对象.appendChild()
:给定子节点 newChild 将成为给定元素节点 element 的最后一个子节点
(2)dom对象.insertBefore(newNode,targetNode)
: 把一个给定节点插入到一个给定元素节点的给定子节点的前面
// 将 newChild 插入到 refChild 的后边
function insertAfter(newChild, refChild){
var refParentNode = refChild.parentNode;
//判断 refChild 是否存在父节点
if(refParentNode){
//判断 refChild 节点是否为其父节点的最后一个子节点
if(refChild == refParentNode.lastChild){
refParentNode.appendChild(newChild);
}else{
refParentNode.insertBefore(newChild, refChild.nextSibling);
}
}
}
- 节点的替换:
1). replaceChild(): 把一个给定父元素里的一个子节点替换为另外一个子节点
var reference = element.replaceChild(newChild,oldChild);
返回值是一个指向已被替换的那个子节点的引用指针
2). 该节点除了替换功能以外还有移动的功能.
3). 该方法只能完成单向替换, 若需要使用双向替换, 需要自定义函数:
/**
* 互换 aNode 和 bNode
*/
function replaceEach(aNode, bNode){
if(aNode == bNode){
return;
}
var aParentNode = aNode.parentNode;
//若 aNode 有父节点
if(aParentNode){
var bParentNode = bNode.parentNode;
//若 bNode 有父节点
if(bParentNode){
var tempNode = aNode.cloneNode(true);
bParentNode.replaceChild(tempNode, bNode);
aParentNode.replaceChild(bNode, aNode);
}
}
}
- 删除节点:
1). 父级dom对象.removeChild(): 删除指定的节点
事件
事件的绑定与解绑
-
绑定:
dom对象.on事件名 = 事件处理函数名
// 此方法只能添加一个事件处理函数。 -
解绑:只需要把事件处理函数的赋值改为null即可
dom对象.on事件名 = null
。 -
绑定:
dom对象.addEventListener("没有on的事件名称", 事件处理函数名, false) ;
此方式可以叠加绑定事件,一个标签绑定多个事件函数。 -
解绑:
dom对象.removeEventListener("没有on的事件名称", 要解绑的事件处理函数名, false) ;
//此方法不能解绑匿名函数。尾部的布尔参数:指定事件是否在捕获或冒泡阶段执行。详细请看下文。 -
绑定:
dom对象.attachEvent("带on的事件名称", 事件处理函数,) ;
仅仅ie8支持,此方法不能解绑匿名函数 -
解绑:
dom对象.detachEvent("带on的事件名称", 事件处理函数,) ;
给节点赋事件的注意:
<button id = "ax"></button>
<script>
function f1() {
alert("弹窗");
}
var eleObj = document.getElementById("ax");
eleObj.onclick = f1; // 注意:此处把f1这个函数给eleObj标签的属性onclick,当按钮被点击时才会触发函数,而不是f1()
// 如果写f1(); 这表明直接调用了,而不是点击触发弹窗
</script>
不同绑定方式的区别
相同点:都可以为元素绑定事件
不同点:
1.方法名不一样
2.参数个数不一样addEventL istener三个参数,attachEvent两个参数
3. addEventListener谷歌,火狐,IE11支持,IE8不支持
attachEvent谷歌火狐不支持,IE11不支持,IE8支持
4. this不同,addEventListener中的this 是当前绑定事件的对象
attachEvent中的this是window
5. addEventListener中事件的类型(事件的名字)没有on
attachEvent中的事件的类型(事件的名字)有on
事件冒泡
- 说明:事件冒泡是指,触发子标签的事件的同时会触发父标签的事件(如果父标签有事件的话)
- 屏蔽事件冒泡:
document.getElementsByTagName("div")[0].onclick = function (e) {
console.log(e);
e.stopPropagation(); //ie不支持
window.event.cancelBubble = true; //ie、谷歌支持 火狐不支持
}
事件的三个阶段
1.事件捕获阶段: 从外向内 dom对象.addEventListener("没有on的事件名称", 事件处理函数名, true);
2.事件目标阶段: 最开始选择的那个
3.事件冒泡阶段: 从里向外 dom对象.addEventListener("没有on的事件名称", 事件处理函数名, false);
4. 获取阶段:e. eventPhase属性会得到值 {1,2,3 }; 1 表示捕获阶段,3表示冒泡阶段,2表示当前阶段。
为同一个元素绑定多个不同的事件,指向相同的事件处理函数
var bu = document.querySelector(".bu");
bu.onclick = f1;
bu.onmouseover = f1;
bu.onmouseout = f1;
function f1(e) {
switch (e.type) {
case "click":
alert("aaaa");
break;
case "mouseover":
this.style.backgroundColor = "red";
break;
case "mouseout":
this.style.backgroundColor = "purple";
break;
}
}
兼容代码
- 获取指定元素的第一个结点,并兼容ie8
function getFirstEleChile(ele) {
if (ele.firstElementChild) { //判断是否是能用.firstElementChild获取浏览器属性
return ele.firstElementChild;
}else{ //如果不能,执行兼容代码
var node = ele.firstChild; //获取第一个子结点
while (node && node.nodeType !== "1") { //如果这个结点不存在,或者不是标签,则向下找,判断node是不是undefined是防止死循环
node = node.nextSibling;
}
return node; //
}
}
- 事件绑定与解绑的兼容代码
//绑定
function addEventListener(element, type, fun) {
if (element.addEventListener) { //判断这个函数是否兼容浏览器,注意:判断的是函数的变量没有()
element.addEventListener(type, fun, false);
}else if (element.attachEvent) { //此方法已经被弃用,仅仅ie8支持
element.attachEvent("on" + type, fun);
}else {
element.["on"+type] = fun; //如果上边的两个都不支持,则用最原始的方式赋事件
}
}
//解绑
function removeEventListener(element, type, fun) {
if (element.removeEventListener) {
element.removeEventListener(type, fun, false);
}else if (element.detachEvent) {
element.detachEvent("on" + type, fun);
}else {
element.["on"+type] = null;
}
}