江民钦的博客

show me code

JS中DOM操作、事件绑定、监听、委托及event对象详解

在JavaScript中最不得不提起的就是对DOM节点的操作以及它的事件机制,对于其中的细节之处,往往是一个前端开发者必须要掌握的。

DOM操作

1.访问节点

document.getElementById(id);
返回对拥有指定id的第一个对象进行访问

document.getElementsByName(name);

返回带有指定名称的节点集合
注意:Elements

document.getElementsByTagName(tagname);
返回带有指定标签名的对象集合
注意:Elements

document.getElementsByClassName(classname);
返回带有指定class名称的对象集合

2.生成节点

document.createElement(eName);
创建一个节点

document.createAttribute(attrName);
对某个节点创建属性

document.createTextNode(text);
创建文本节点

3.添加节点
document.insertBefore(newNode,referenceChild);
在某个节点前插入节点

parentNode.appendChild(newNode);
给某个节点添加子节点

4.复制节点

cloneNode(true | false);
复制某个节点
参数:是否复制原节点的所有属性

5.删除节点

parentNode.removeChild(node)
删除某个节点的子节点
node是要删除的节点

6.修改文本节点

appendData(data);
将data加到文本节点后面

deleteData(start,length);
将从start处删除length个字符

insertData(start,data)
在start处插入字符,start的开始值是0;

replaceData(start,length,data)
在start处用data替换length个字符

splitData(offset)
在offset处分割文本节点

substringData(start,length)
从start处提取length个字符

7.属性操作

getAttribute(name)
通过属性名称获取某个节点属性的值

setAttribute(name,value);
修改某个节点属性的值

removeAttribute(name)
删除某个属性

8.查找节点

parentObj.firstChild
如果节点为已知节点的第一个子节点就可以使用这个方法。此方法可以递归进行使用
parentObj.firstChild.firstChild…..

parentObj.lastChild
获得一个节点的最后一个节点,与firstChild一样也可以进行递归使用
parentObj.lastChild.lastChild…..

parentObj.childNodes
获得节点的所有子节点,然后通过循环和索引找到目标节点

9.获取相邻的节点

neborNode.previousSibling :获取已知节点的相邻的上一个节点
nerbourNode.nextSlbling: 获取已知节点的下一个节点

10.获取父节点

childNode.parentNode:得到已知节点的父节点

11替换节点

方法replace(new,old)

JS innerHTML和innerText区别

1、innerHTML:
  也就是从对象的起始位置到终止位置的全部内容,包括Html标签。
2、innerText:
 从起始位置到终止位置的内容, 但它去除Html标签

事件机制

总所周知,在JavaScript中事件采用绑定监听这种形式。我们可以在DOM元素上绑定onclick、onmouseover、onmouseout、onmousedown、onmouseup、ondblclick、onkeydown、onkeypress、onkeyup等

在JavaScript代码中绑定事件

1
2
3
4
5
6
<input type="button" value="click me" id="btn">
<script>
document.getElementById("btn").onclick = function(){
alert("hello world!");
}
</script>

在html中添加事件函数

1
2
3
4
5
6
<input type="button" value="click me" id="btn" onclick="btnClick()">
<script>
function btnClick(){
alert("hello world!");
}
</script>

绑定事件监听器

W3C规范

语法:

element.addEventListener(event, function, useCapture)

event : (必需)事件名,支持所有 DOM事件 。

function:(必需)指定要事件触发时执行的函数。

useCapture:(可选)指定事件是否在捕获或冒泡阶段执行。true,捕获。false,冒泡。默认false。
注:IE8以下不支持。

IE标准

语法:

element.attachEvent(event, function)

event:(必需)事件类型。需加“on“,例如:onclick。

function:(必需)指定要事件触发时执行的函数。

1
2
3
4
5
6
7
<input type="button" value="click me" id="btn">
<script>
document.getElementById('btn').addEventListener("click", btnClick, false);
function btnClick(){
alert("hello world!");
}
</script>

移除事件

element.removeEventListener(event,function);
IE下:element.detachEvent(event,function);

事件模型

但值得注意的是JavaScript中事件模型分为两种————冒泡模型和捕获模型,也称事件冒泡和事件捕获。
(1)事件冒泡:指事件按照从最特定的事件目标到最不特定的事件目标的顺序触发。通俗一点,在html文档中,DOM节点成呈树状结构,从最特点的事件目标即直接发生的DOM节点到最不特点发生的事件目标即html的document对象传递,这个过程称为事件冒泡。
(2)事件捕获:事件从最不精确的document对象开始触发,到最特定最精确的事件目标。简而言之,就是和事件冒泡完全相反的两个动作。
(3)DOM事件流:同时支持两种事件模型:捕获型事件和冒泡型事件,但是,捕获型事件先发生。两种事件流会触及DOM中的所有对象,从document对象开始,也在document对象结束。
DOM事件模型最独特的性质是,文本节点也触发事件(在IE中不会)。

事件委托

事件委托就是利用冒泡的原理,把事件加给父元素或祖先元素上,触发执行效果。事件委托的有点,可以避免多个同类型节点添加同一事件处理,减少内存占用,提高事件的处理速度,优化网页性能。

比如给一个里边的每一项添加事件:

传统写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<ul id="group">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
<script>
var items=document.getElementsByTagName('li');
for(var i=0;i<items.length;i++){
items[i].onclick=function(){
this.style.color='red';
}
}
</script>

事件委托写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
<ul id="group">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
<script>
var group=document.getElementById('group');
group.onclick=function(event){
var target=event.target;
target.style.color='red';
}
</script>

当然函数阻止事件冒泡可以使用event.stopPropagation().
还有阻止事件的默认行为的方法有event.preventDefault()

Event对象

  1. type:事件的类型,如onlick中的click;

  2. srcElement/target:事件源,就是发生事件的元素;

  3. button:声明被按下的鼠标键,整数,1代表左键,2代表右键,4代表中键,如果按下多个键,酒把这些值加起来,所以3就代表左右键同时按下;(firefox中 0代表左键,1代表中间键,2代表右键)

  4. clientX/clientY:事件发生的时候,鼠标相对于浏览器窗口可视文档区域的左上角的位置;(在DOM标准中,这两个属性值都不考虑文档的滚动情况,也就是说,无论文档滚动到哪里,只要事件发生在窗口左上角,clientX和clientY都是 0,所以在IE中,要想得到事件发生的坐标相对于文档开头的位置,要加上
    document.body.scrollLeft和 document.body.scrollTop)

  5. offsetX,offsetY/layerX,layerY:事件发生的时候,鼠标相对于源元素左上角的位置;

  6. x,y/pageX,pageY:检索相对于父要素鼠标水平坐标的整数;

  7. altKey,ctrlKey,shiftKey等:返回一个布尔值;

  8. keyCode:返回keydown何keyup事件发生的时候按键的代码,以及keypress 事件的Unicode字符;(firefox2不支持 event.keycode,可以用 event.which替代 )

  9. fromElement,toElement:前者是指代mouseover事件中鼠标移动过的文档元素,后者指代mouseout事件中鼠标移动到的文档元素;

  10. cancelBubble:一个布尔属性,把它设置为true的时候,将停止事件进一步起泡到包容层次的元素;(e.cancelBubble = true; 相当于 e.stopPropagation();)

  11. returnValue:一个布尔属性,设置为false的时候可以组织浏览器执行默认的事件动作;(e.returnValue = false; 相当于 e.preventDefault();)

  12. attachEvent(),detachEvent()/addEventListener(),removeEventListener:为制定 DOM对象事件类型注册多个事件处理函数的方法,它们有两个参数,第一个是事件类型,第二个是事件处理函数。在
    attachEvent()事件执行的时候,this关键字指向的是window对象,而不是发生事件的那个元素;

  13. screenX、screenY:鼠标指针相对于显示器左上角的位置,如果你想打开新的窗口,这两个属性很重要;