DOM树 DOM: Document Object  Model
使用对象的方式描述对应的html
API 规范,
浏览器中的JS 包含 DOM 通过JS 调用 API 操作浏览器操作 DOM树。
DOM 树:节点(node) 层次,文档节点(document)、元素节点、属性节点、文本节点。
节点遍历
 
以p节点为参考对象node,
node.parentNode = body
node.firstChild = hello,
node.lastChild = img
node.previousSibling = null
node.nextSibling = div
节点类型
 
element_node 元素节点(body, p, div, span, img)
text_node 文本节点(hello, mooc, 为专业)
comment_node
document_type_node
元素遍历
 
p 的第一个元素节点是 em,p的最后一个元素节点是 a
em.nextElementSibling = a,em.previousElementSibling = null
如何兼容浏览器版本的element.children element.children能够获取元素的元素子节点,但是低版本的ie不支持,如何在低版本的ie上兼容类似的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function  getElementChildren (element ) 	      if  (element.children) {         return  element.children;     } else  {          var  list = [];          var  nodelist = element.childNodes;          for  (var  i = 0 ; i < nodelist.length; i++) {             if (nodelist[i].nodeType == 1 ){             	                   list.push(nodelist[i]);             }         }         return  list;     } } 
节点操作 —
1 2 3 4 5 <div  id ="mydiv" >     <span  id ="span1" > 1</span >      <span  id ="span2" > 2</span >      <span  id ="span3" > 3</span >  </div > 
1 2 3 4 5 6 7 8 var  mydiv = document .querySelector('#mydiv' );mydiv.firstChild;  mydiv.firstElementChild;  mydiv.lastChild;  mydiv.lastElementChild;  mydiv.childNodes;  mydiv.children;  
节点还包括 text 节点,标签与标签之间的文本信息,也算一个结点。
1 2 3 4 5 var  span1Ele = document .querySelector('#span1' );     span1Ele.parentNode;  span1Ele.nextSibling;  span1Ele.nextElementSibling;  
节点方法名:
方法名 
返回值类型 
说明 
 
 
hasChildNodes() 
Boolean 
当前节点是否有子节点 
 
appendChild(node) 
Node 
往当前节点上添加子节点 
 
removeChild(node) 
Node 
删除子节点 
 
replaceChild(oldNode, newNode) 
Node 
替换子节点 
 
insertBefore(newNode, refNode) 
Node 
在指定节点前插入新结点 
 
小练习:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <span  id ="span1" > span1</span > <span  id ="span2" > span2</span > <div  id ="div1"  style ="background: palegreen" > 1</div > <div  id ="div2"  style ="background: palegoldenrod" > 2</div > <div  id ="div3"  style ="background: palevioletred" > 3</div > <button  onclick ="fun1()" > 把 span1 添加到 div1</button > <button  onclick ="fun2()" > 把 span2 添加到 div2</button > <button  onclick ="fun3()" > 创建span元素添加到div3</button > <br /> <select  id ="character"  size ="7" >     <option  id ="item1" > 刘备</option >      <option  id ="item2" > 关羽</option >      <option  id ="item3" > 张飞</option >      <option  id ="item4" > 赵云</option >  </select > <button  onclick ="fun4()" > 在关羽之前插入诸葛亮</button > <button  onclick ="fun5()" > 把关羽换成魏延</button > <button  onclick ="fun6()" > 删除张飞</button > 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 function  fun1 (    var  span1 = document .querySelector('#span1' );     var  div1 = document .querySelector('#div1' );     div1.appendChild(span1);  } function  fun2 (    var  span2 = document .querySelector('#span2' );     var  div2 = document .querySelector('#div2' );     div2.appendChild(span2);  } function  fun3 (    var  span3 = document .createElement('span' );     span3.innerHTML = "span3" ;     span3.id = 'span3'      var  div3 = document .querySelector('#div3' );     div3.appendChild(span3);  } function  fun4 (    var  sels = document .querySelector('#character' );     for  (var  childrenKey in  sels.children) {         var  op = sels.children[childrenKey];         if  (op.innerHTML == '关羽' ) {             var  option = document .createElement('option' );             option.id = 'item'  + childrenKey;             option.innerHTML = "诸葛亮" ;             sels.insertBefore(option, op);             break ;         }     } } function  fun5 (    var  sels = document .querySelector('#character' );     for  (var  childrenKey in  sels.children) {         var  op = sels.children[childrenKey];         if  (op.innerHTML == '关羽' ) {             var  option = document .createElement('option' );             option.id = 'item'  + (parseInt (childrenKey) + 1 );             option.innerHTML = "魏延" ;             sels.replaceChild(option, op);             break ;         }     } } function  fun6 (    var  sels = document .querySelector('#character' );     for  (var  childrenKey in  sels.children) {         var  op = sels.children[childrenKey];         if  (op.innerHTML == '张飞' ) {             sels.removeChild(op);             break ;         }     } } 
获取节点 通过已获取到的节点的DOM数,可以获取节点
父子关系:
parentNode  
firstChild/lastChild/childNodes  
childNodes/children 
 
兄弟关系:
previousSibling/nextSibling 
previousElementSibling/nextElementSibling 
 
 
这样获取节点的可维护性差
 
getElementById, 返回一个元素 getElementsByTagName, 返回集合 返回值是动态的,对节点操作,会影响其取值的变化。
通过这个方法可以获取指定元素下所有的后代元素。
getElementsByClassName, 返回集合 collection,返回的是集合,集合是动态的, 如果删除掉其中的一个值,则collection 中的值也会改变。
通过空格分隔,指定多个类名。和类名的顺序没什么关系。
ie 6 7 8 并不兼容 getElementsByClassName
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 function  getElementByClassName (element, classNames ) 	if  (element.getElementByClassName) {  		return  element.getElementByClassName(classNames); 		 	} else  { 		 		var  elements = element.getElementsByTagName('*' ); 		 		var  result = []; 		var  element, classNameStr, flag; 		classNames = classNames.split(' ' ); 		 		for (var  i = 0 ; element = elements[i]; i++) { 			classNameStr = ' '  + element.className + ' ' ; 			flag = true ; 			 			for (var  j = 0 , className; className = classNames[j]; j++) { 				if  (classNameStr.indexOf(' '  + name + '' ) == -1 ) { 					flag = false ; 					break ; 				} 			} 			if  (flag) { 				result.push(element); 			} 		} 		return  result; 	} } function  hasClassName (element, className ) 	return  element.className == className;	 } 
querySelector/ALL list = element.querySelector/All(selector)  
list 不是动态的,反映在如果获取了节点所有的元素,如果我们删掉了其中一个。list内部的值并未改变。
前者获取第一个符合条件的元素,后者获取所有符合条件的元素。
此时,users 获取到的是 div单个元素 div#users
1 2 3 4 users.querySelectorAll(".user" ) document.querySelectorAll(#users .user"); 
querySelector 返回的列表是静态的!
live: 动态集合
sole: 单一的
only document: 节点
创建节点 
创建节点:
createElement,
element = document.createElement(tagName)
创建指定标签的元素。
设置节点内容 element.textContent 节点及其后代节点的文本内容。ie9 不支持
element.innerText 节点及其后代节点的文本内容。  常用(不规范, ff 不支持)
平台兼容方案:
插入节点 appendChild var achild = element.appendChild(achild);
在指定元素的最末尾,追加元素
insertBefore, var achild = element.insertBefore(achild, referenceChild);
将节点插入到指定元素的前面。
ul.insertBefore(li, ul.firstChild);
删除节点 removeChild,
child = element.removeChild(child)
删除element 指定的子元素
user2.parentNode.removeChild(user2);
innerHTML 提高效率 节点的 HTML 内容,建议仅用于新节点。内容可控,不是用户填写的内容,如果是用户填写的内容也要确保内部没有标签
低版本的ie 内存泄露,
安全问题:
修改属性 每一个html属性对应相应的 DOM 对象属性
HTML attribute -> DOM property
input.id  input.type input.className 
label.htmlFor = username
属性访问器 来操作对象 读取属性 input.className  input[“id”]  
属性写 
input.value = ‘wwq@163.com ‘
其实是在 标签内加入了 value 属性 并且赋值为 wwq@163.com 
input.disabled = true;
input.className = “u-txt” String
input.maxLenth = 10  Number
input.disabled = true  Boolean
input.onclick = function onclick(event){}  Function
通过属性访问修改的属性,会转会进行类型转换,从字符串 转换到实用对象 
用属性访问器来操作对象
通用性比较差, 名字异常
扩展性 比较差
取到的是实用对象,可以直接实用。
用 get / setAttribute 来操作对象 读 var attribute = element.getAttribute(attributeName);
input.getAttribute(“class”)  // “u-txt”
写 element.setAttribute(name, value);
input.setAttribute(“value”, “wwq@163.com “);
input.setAttribute(“disabled”, “”);
get / setAttribute 来操作对象 纯粹是字符串的操作
get / setAttribute 来操作对象 特点
 
仅字符串  通用性好 
案例:
为了防止重复点击登录按钮,重复发送请求,要在点击之后,改变登录按钮的样式
两种方式都能进行属性改变,如果是纯字符串操作,可以使用 get/setAttribute 如果是 实用类型,则实用属性访问器
dataset HTMLElement.dataset
data-* 属性集
用途: 元素上保存数据
例子:
如何实现浏览器兼容版的 element.dataset
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 function  getDataset (element )                   element.dataset = {};     var  attrs = element.attributes;      for (var  i = 0 ; i < attrs.length; i++) {         if  (/^data-/ .test(attrs[i].name)) {          	             var  key = attrs[i].name.match(/^data-(.+)/ )[1 ];                          var  value = attrs[i].value;                          key = key.replace(/-\w/g ,function (match )                  return  match.substring(1 ).toUpperCase();             });             element.dataset[key] = value;         }     }     return  element.dataset;      } 
样式操作 js 动态修改样式
CSS 的外部样式链接表:获取元素
获取内部样式:element.sheet
以上两种样式链接表可以通过 document.styleSheets 获取
CSSStyleDeclaration 是CSS属性名和属性值键值对的列表。
获取标签内部样式:element.style
更新样式 标准做法一:style.cssText(这种方式不够好)
标准做法二:更新class
换肤(更换样式表) 一次性更新很多元素
更换样式表:$(‘skin’).href = “skin.summer.css”;
1 2 3 function  $ (id ) 	return  document .getElementById(id); } 
获取样式 element.style 对应元素内嵌样式表 这样没办法获取到实际样式
只有设置了内嵌 style 属性的元素,才能通过element.style获取到元素的样式。
通过 window.getComputedStyle() var style = window.getComputedStyle(element, pseudoElt]);
返回 style 是一个只读的 CSSStyleDeclaration 类型的属性
window.getComputedStyle(element).color // “rgb(0, 0, 0)”
获取到实际的颜色
ie9 不支持, ie9 会用element.currentStyle 做兼容
CSS DOM overview(概览) StyleSheetList[0] 获取到具体样式表 -> CSSStyleSheet
如何实现兼容版的 window-getComputedStyle 1 2 3 4 5 6 7 8 function  getStyle (element )          if (window .getComputedStyle) {         return  window .getComputedStyle(element);     } else  if (element.currentStyle) {         return  element.currentStyle;     } } 
实现getStyle函数 getStyle函数用于获取元素的实际样式,语法如下:
var cssPropertyValue = getStyle (element, cssPropertyName);
使用示例如下:
1 2 3 4 5 6 7 function  getStyle (element,attr )     if (window .getComputedStyle) {         return  getComputedStyle(element)[attr];     } else  {         return  element.currentStyle[attr];     } } 
DOM 事件 什么是 DOM 事件?
点击一个 DOM 事件、键盘按下一个键等等
需要记住的事件属性 
onblur 元素失去焦点 
onclick 鼠标点击 
onchange 文本域改变、用户改变域的内容 
 
JS事件参考手册  
小练习:
1 <img  id ="img"  src ="lady.jpg"  width ="400"  height ="300" /> 
1 2 3 4 var  imgEle = document .querySelector('#img' );imgEle.onmouseover = function  (     this .src = 'supperman.png' ; } 
练习1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <!DOCTYPE html> <html lang="en" > <head>     <meta charset="UTF-8" >     <title>Title</title>      <script>         function checkAll(flag) {             var all = document.getElementsByName('hobby')             var checkAll = document.querySelector('#checkAll')             checkAll.checked = flag;             for (var allKey in all) {                 all[allKey].checked = flag;             }         }         function checkUnAll() {             var all = document.getElementsByName('hobby')             var checkAll = document.querySelector('#checkAll')             var flag = true;             for (var allKey in all) {                 all[allKey].checked = !all[allKey].checked                 if (all[allKey].checked == false) {                     flag = false;                 }             }             checkAll.checked = flag         }     </ script></head>  <body> 请选择你的爱好: <input type="checkbox" onchange="checkChange()" id="checkAll"/ >全选/全不选 <br/><div>     <input type="checkbox"  name="hobby" />JAVA      <input type="checkbox"  name="hobby" />打篮球      <input type="checkbox"  name="hobby" />上网      <input type="checkbox"  name="hobby" />撩妹  </div>  <div>     <input type="button" id="btn_checkAll" onclick="checkAll(true)" value="全选"/ >    <input type="button"  onclick="javascript:checkAll(false)"  value="全不选" />     <input type="button"  onclick="checkUnAll()"  value="反选" /> </div>  </ body></html>  
练习2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 <!DOCTYPE html> <html lang="en" > <head>     <meta charset="UTF-8" >     <title>Title</title>      <script>         function moveSelected(id1, id2) {             var selectSrc = document.querySelector('#' + id1);             var selectDir = document.querySelector('#' + id2);             var options = selectSrc.selectedOptions;             while (options.length > 0) {                 selectDir.appendChild(options[0])             }         }         function moveAll(id1, id2) {             var selectSrc = document.querySelector('#' + id1);             var selectDir = document.querySelector('#' + id2);             var options = selectSrc.options;             while (options.length > 0) {                 var ele = selectSrc.options[0]                 selectDir.appendChild(ele)             }         }     </ script></head>  <body> <table border="1">     <tr>         <td width="50">             <select id="select1" size="10" multiple="multiple">                 <option value="选项1">选项1</ option>                <option value="选项2" >选项2 </option>                  <option value="选项3">选项3</ option>                <option value="选项4" >选项4 </option>                  <option value="选项5">选项5</ option>                <option value="选项6" >选项6 </option>                  <option value="选项7">选项7</ option>                <option value="选项8" >选项8 </option>                  <option value="选项9">选项9</ option>            </select>          </ td>        <td align="center" >             <input type="button"  onclick="moveSelected('select1', 'select2')"  value="-->" /><br />              <input type="button"  onclick="moveAll('select1', 'select2')"  value="==>" /><br />              <input type="button"  onclick="moveSelected('select2', 'select1')"  value="<--" /><br />              <input type="button"  onclick="moveAll('select2', 'select1')"  value="<==" />         </td>          <td width="50">             <select id="select2" size="10" multiple="multiple">             </ select>        </td>      </ tr></table>  </ body></html>  
jqury 版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 <!DOCTYPE html> <html lang="en" > <head>     <meta charset="UTF-8" >     <title>Title</title>      <script src="static/ jquery/jquery-1.11 .3 .min.js"></script>     <script>         $(function () {             var checkHobbyState = function() {                 // 只有4个爱好选中时 修改全选的标识                 var sum = true;                 $('input[name=hobby]').each(function (index, domEle) {                     sum = sum && $(domEle).prop('checked')                 })                 $('#checkAll').prop('checked', sum)             }             $('#checkAll').change(function () {                 $('input[name=hobby]').prop('checked', $(this).prop('checked'))             })                          $('#btn_checkAll').click(function () {                 $('input[name=hobby]').prop('checked', true)                 checkHobbyState()             })             $('#btn_checkUnAll').click(function () {                 $('input[name=hobby]').prop('checked', false)                 checkHobbyState()             })             $('#btn_checkReverse').click(function () {                 $('input[name=hobby]').prop('checked', function (index, checkedValue) {                     return !checkedValue                 })                 checkHobbyState()             })         })         // foreach 底层原理         Array.prototype.foreach2 = function (fn) {             for (var i = 0; i < this.length; i++) {                 fn(this[i], i, this)             }         }         var arr = ['1', '2', '3']         arr.forEach(function (value, index) {             console.log(value);             console.log(index);         })         // map 底层原理         Array.prototype.map2 = function (fn) {             var newArr = []             for (var i = 0; i < this.length; i++) {                 var result = fn(this[i], i, this)                 newArr.push(result)             }             return newArr         }         var newA2 = arr.map2(function (value, index, array) {             return '1' + value         })         console.log(newA2);     </script> </head> <body> 请选择你的爱好: <input type=" checkbox" id=" checkAll"/>全选/全不选 <br/> <div>     <input type=" checkbox" name=" hobby"/>JAVA      <input type=" checkbox" name=" hobby"/>打篮球      <input type=" checkbox" name=" hobby"/>上网      <input type=" checkbox" name=" hobby"/>撩妹  </div> <div>     <input type=" button" id=" btn_checkAll" value=" 全选"/>     <input type=" button" id=" btn_checkUnAll" value=" 全不选"/>     <input type=" button" id=" btn_checkReverse" value=" 反选"/> </div> </body> </html> 
练习3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 <!DOCTYPE html> <html lang="en" > <head>     <meta charset="UTF-8" >     <title>Title</title>      <script>         window.onload = function () {             var removeAll = document.querySelector('#btn_removeAll');             removeAll.onclick = function () {                 var ele = document.querySelector('#userTbody')                 ele.innerHTML = ''             }             var trId = 1;             var btn_submit = document.querySelector('#btn_submit')             btn_submit.onclick = function () {                 / / 找到所有 input 输入文本值                 var username = document.querySelector('#username').value                 var email = document.querySelector('#email').value                 var tel = document.querySelector('#tel').value                 / / 创建 tr td 并 td 加到 tr 中                 var usernameTdEle = document.createElement('td')                 usernameTdEle.innerHTML = username                 var emailTdEle = document.createElement('td')                 emailTdEle.innerHTML = email                 var telTdEle = document.createElement('td')                 telTdEle.innerHTML = tel                 var optionTdEle = document.createElement('td')                 optionTdEle.innerHTML = '<a href="javascript:delRow(\'tr' + trId + '\')">删除</ a>'                 var trEle = document.createElement(' tr')                 trEle.id = ' tr' + trId;                 trId++                 trEle.appendChild(usernameTdEle)                 trEle.appendChild(emailTdEle)                 trEle.appendChild(telTdEle)                 trEle.appendChild(optionTdEle)                 // 把 tr 加到 tbody 中                 var tbody = document.querySelector('#userTbody')                 tbody.appendChild(trEle)             }         }         function  delRow (id )              var  removeAll = document .querySelector('#'  + id);             removeAll.parentNode.removeChild(removeAll);         }     </script>  </ head><body> <form name="userForm" >     <center>         用户录入<br/>         用户名:<input id="username"  name="username"  type="text"  size="15" />         E-mail:<input id="email"  name="email"  type="text"  size="15" >         电话:<input id="tel"  name="tel"  type="text"  size="15" >         <input type="button"  value="添加"  id="btn_submit" >         <input type="button"  value="删除所有"  id="btn_removeAll" >     </center>  </ form><hr/> <table border="1"  align="center"  cellpadding="0"  cellspacing="0"  width="400" >     <thead>     <tr>         <th>用户名</th>          <th>E-mail</ th>        <th>电话</th>          <th>操作</ th>    </tr>      </ thead>    <tbody id="userTbody" >     <tr id="tr1" >         <td>张无忌</td>          <td>wujizhang@163.com</ td>        <td>18212345678 </td>          <td><a href="javascript:delRow('tr1')">删除</ a></td >     </tr>      </ tbody></table>  </ body></html>  
jquery 版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 <!DOCTYPE html> <html lang="en" > <head>     <meta charset="UTF-8" >     <title>Title</title>      <script src="static/ jquery/jquery-1.11 .3 .min.js"></script>     <script>         $(function () {             var trId = 2             $('#btn_removeAll').click(function () {                 $('#userTbody').empty()             })             $('#btn_submit').click(function () {                 // 找到所有 input 输入文本值                 var username = $('#username').val()                 var email = $('#email').val()                 var tel = $('#tel').val()                 // 模板字符串                 var a = `                     <tr id=" tr${trId}">                         <td>${username}</td>                         <td>${email}</td>                         <td>${tel}</td>                         <td><a href=" javascript:delRow('tr${trId}' )">删除</a></td>                     </tr>                 `;                 $('#userTbody').append(a)                 trId ++;             })         })         function delRow(id) {             $('#' + id).remove();         }     </script> </head> <body> <form name=" userForm">     <center>         用户录入<br/>         用户名:<input id=" username" name=" username" type=" text" size=" 15 "/>         E-mail:<input id=" email" name=" email" type=" text" size=" 15 ">         电话:<input id=" tel" name=" tel" type=" text" size=" 15 ">         <input type=" button" value=" 添加" id=" btn_submit">         <input type=" button" value=" 删除所有" id=" btn_removeAll">     </center> </form> <hr/> <table border=" 1 " align=" center" cellpadding=" 0 " cellspacing=" 0 " width=" 400 ">     <thead>     <tr>         <th>用户名</th>         <th>E-mail</th>         <th>电话</th>         <th>操作</th>     </tr>     </thead>     <tbody id=" userTbody">     <tr id=" tr1">         <td>张无忌</td>         <td>wujizhang@163.com</td>         <td>18212345678</td>         <td><a href=" javascript:delRow('tr1' )">删除</a></td>     </tr>     </tbody> </table> </body> </html> 
事件流 
会从事件的最顶端,window 开始往下 捕获到触发事件节点的父元素,即 p 元素
事件触发过程。
从事件响应的起 冒泡的 window 对象。
有些事件没有冒泡过程, 一些低版本浏览器没有 capture 过程。
事件注册与触发 事件注册 、事件触发、 事件取消注册
事件注册 eventTarget.addEventListener(type, listener[, useCapture])
使用第二种事件注册方法,有个弊端,只能注册一个函数。实际上可以有多个函数响应该事件。
取消事件注册 eventTarget.removeEventListener(type, listener[, useCapture])
事件触发 eventTarget.dispatchEvent(type)
浏览器兼容 ie6、7、8 没有采用该标准 
attchEvent/detachEvent
fireEvent(e)
js 的 addEventListener 和 removeEventListener 的兼容
 
事件对象 
ie 的 低版本:不是通过函数传入 event对象,而是将事件对象放在 window.event中,兼容方式:
属性 
type 
target(sourceElement) 
currentTarget(当前处理事件节点),有可能处理函数是注册在 target 父节点上 
 
方法 
stopPropagation 阻止传播,不想继续冒泡了(w3c)
event.cancelBubble = true(IE) 
 
 
stopImmediatePropagation 阻止冒泡
阻止事件传播到父节点 
阻止当前节点的后续事件(在我后面注册的事件不会传播) 
 
 
preventDefault 阻止默认行为(w3c)
event.returnValue = false(IE) 
 
 
 
阻止默认行为,比如点击链接,会默认打开链接。可以使用该方法阻止事件响应。
事件分类 
MouseEvent 
mouseover、mouseout 与 mouseenter、mouseleave 的区别
加入 div 有子元素, 我们鼠标离开 div 元素 进入到 div 中的子元素上,都会触发 mouseover 、 mouseout
mouseenter、mouseleave 只有进入这个元素就会触发,进入该元素的子元素不会触发。而出这个 div 元素。将 div 看成一个整体,进入或移出这个整体会触发。
属性 
clientX, clientY 
screenX, screenY 
 
ctrlKey, shiftKey, altKey, metaKey 
 
如果事件触发时,这几个键是按下去的,则这些属性为 true 否则为false
button(0,1,2)分别代表按下鼠标的键是左键还是右键 
 
MouseEvent 顺序 
从元素A上方移过:
mousemove -> moseover(A) -> mouseenter(A) -> mousemove(A)(多次) -> mouseout(A) -> mouseleave(A) 
 
 
点击元素
mousedown -> [mousemove] -> mouseup -> click 
 
 
 
例子 拖拽div 
WheelEvent对象 事件类型: wheel 是否冒泡: YES  元素:Element
属性:
deltaMode(delta值的单位) 
deltaX 
deltaY 
deltaZ 
 
x y z 轴上的偏移量
FocusEvent 
属性:
relatedTarget 当一个元素失去焦点时,获得焦点的元素就是 relatedTarget,当一个元素获得焦点时,失去焦点的元素就是 relatedTarget。 
 
ie 兼容:
onpropertychange
KeyboardEvent 处理键盘事件 比如回车键,等
属性:
key: 你按下的什么键 字符串 
code:按键码 
ctrlKey、shiftKey、altKey、metaKey 用来标识这些键有没有按下去 
repeat: 持续按一个键,值是true 
keyCode:获取键盘的键的ASK码 
charCode: 
which 
 
Event 其他事件类型 
依赖网络加载的事件,加载完成时会触发,
unload 指 页面退出的时候出发
error 出现在加载错误
selected 通常 input textarea 被选择了 会触发
abort 退出事件,Window image上,比如图片加载时,按了 esc 会触发
window对象 
load 当页面上所有的请求都完成时,会触发 load 
unload 当文档退出的时候,比如关闭当前页面,离开当前页面 
error 浏览器加载异常 
abort 离开页面 
 
image 
load 图片加载完成 
error 图片加载异常 
abort 当图片加载时,按esc 会触发 
 
一般这样通用:
如果指定图片加载不到,会显示默认图片。
UIEvent resize 通常在修改窗体大小的时候,修改浏览器窗体大小,iframe窗体大小
scroll 指页面发生滚动时触发。元素上触发会冒泡
元素上触发scroll会冒泡,document上触发Scroll 不会冒泡
事件代理 将事件注册到元素的父节点上,对于ul li 一组标签来说,将事件注册到父元素上,这样简化事件注册。
触发事件的方式 
为什么 JavaScript 中的函数需要用 window.onload 包起来?
 
window.onload 方法的作用是在页面的所有元素都加载完毕后才会触发,包括图片。当连接质量不好的时候,会导致该方法触发延迟。当然你也可以在 body 后写 script 代码,但是这样不符合习惯。
1 <button  id ="btn" > 点击</button > 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 window .onload = function  (    var  btn = document .querySelector('#btn' );          btn.onclick = function  (         console .log(1 );     };               btn.addEventListener('click' , function  (         console .log(2 );     })               var  listener = function  (         console .log(3 );     }     btn.addEventListener('click' , listener);     btn.removeEventListener('click' , listener);               function  addEvent (btn, eventName, func )                   if  (btn.attachEvent) {             btn.attachEvent('on' , eventName, func);         } else  {             btn.addEventListener(eventName, func);         }     } }