BOM VS DOM:
1 BOM:浏览器对象模型(API),专门操作浏览器窗口的API 2 没标准! 3 DOM:文档对象模型(API),专门操作网页内容的API 4 可以对网页中任意对象,做任意修改! 5 DOM是标准,90%以上浏览器都严格兼容 6 核心DOM:操作所有结构化文档(XML,HTML)的通用API 7 HTML DOM:针对HTML文档的简化API 8 HTML DOM不能完成所有功能,实际开发中都是核心DOM与HTML DOM配合使用 9 HTML DOM:网页中一切都是对象(元素,属性,文字) 10 同一网页中所有对象,在内存中父子相连,形成一棵DOM树
2.***DOM树
1 文档中的元素、属性、文本、注释等都被看成一个节点对象--Node--所有节点对象的父类型 2 当网页被加载进内存时,浏览器会为网页创建一个document对象。所有节点对象都是document对象的子节点。 3 document(树根),封装了对网页中所有子节点的增加,删除,查找 4 5 Node类型定义了3个公共属性: 6 nodeType:节点的类型的数值 7 何时使用:专门用于判断获得的节点类型 8 如果是元素节点,返回1 9 如果是文本节点,返回3 10 nodeName:节点的名称 11 何时使用:专门用于判断获得的标签名 12 如果是元素节点,返回标签名 13 **强调:nodeName返回的都是全大写标签名 14 如果是文本节点,返回#text 15 16 nodevalue:节点的值: 17 元素节点,返回null 18 文本节点,返回文本的内容 19 20 childNode:获得当前节点对象下的所有子节点 21 类数组对象,[i] .length 22 23 DOM树6种关系:6个属性: 24 父子:4个:parentNode childNode firstChild lastChild 25 兄弟:2个:previousSibling nextSibling 26 27 childNodes:类数组对象,***动态集合***:自己不保存任何实际数据 28 每使用一次都重新查找一遍 29 for(var i=0;i<parent.childNodes.length;i++) X 30 for(var i=0;len=parent.childNodes.length;i
3.****遍历:
1 从指定父元素开始,按照深度优先的原则 遍历所有各级子节点 2 2步: 3 1.定义一个函数,查找任意父节点下的所有直接子节点 4 2.以深度优先为原则,递归调用函数本身 5 6 何时使用递归调用:2个 7 1.遍历不确定层级深度的树形结构时 8 比如:网页中的元素,网盘中的文件夹结构 9 2.不确定层级深度的多级管理结构: 10 11 元素树:仅由元素节点组成的树结构 12 其实有一组和节点树6个属性对应的元素树属性 13 节点树 元素树 14 父对象 parentNode parentElementNode 15 所有子对象 childNodes children 16 第一个子对象 firstChild firstElementChild 17 最后子对象 lastChild LastElementChild 18 19 前一个兄弟 previousSibling previousElementSibling 20 后一个兄弟 nextSibling nextElementSibling 21 22 何时使用:只要仅希望遍历元素节点时,就用元素树 23 问题:IE8不兼容,children可用 24 25 DOM level2:遍历API:2个--选学 26 1.深度优先遍历:NodeIterator 27 节点迭代器 28 如何使用:2步: 29 1.创建遍历API对象: 30 var iterator=document.createNodeIterator( 31 开始的父节点对象, 32 whatToShow, 33 null,false 34 ); 35 whatToShow:NodeFilter.SHOW_ELEMENT 36 NodeFilter.SHOW_ALL 37 2.用while循环,反复调用iterator.nextNode()方法 38 强调:1.只要nextNode(),就向下移动一次 39 2.iterator.previousNode(),后退一次 40 41 2.自由遍历:TreeWalker 42 使用几乎相同,只不过TreeWalker比Iterator多个别方法 43 44 总结:4种:节点树 元素树 45 API(NodeIterator,TreeWalker)
4.*查找:
1 5个API: 2 1.按ID查找:var elem=document.getElementById("id值"); 3 2.按标签名查找:(向下爬树的主要手段) 4 var elems=parent.getElementsByTagName("标签名"); 5 ***elems也是动态集合*** 6 3.按name属性查找:(专门用于查找表单中的元素) 7 var elems=document.getElementsByName("name属性值"); 8 ***elems也是动态集合*** 9 4.var elems=parent.getElementsByClass ***elems也是动态集合*** 10 for(var i=0,len=elems.length;i<len;i++) 11 12 5.Selector API:jQuery的核心 13 var elems=parent.querySelectorAll("任意选择器") 14 elems:包含所有属性和方法的完整对象的集合 15 for(var i=0;i
5.获取或修改元素内容
1 3个属性: 2 1.innerHTML:获得/设置元素开始标签和结束标签之间的html原文 3 何时使用:只要获得html原文内容时 4 固定套路:2个: 5 1.删除父元素下所有子元素 6 parent.innerHTML=""; 7 2.批量替换父元素下所有子元素 8 parent.innerHTML="所有子元素标签组成的html" 9 比如:ul.innerHTML="<li>电影li><li>剧集li>" 10 2.textContent/innerText:获得开始标签和结束标签之间的纯文本内容,不包含标签 11 DOM标准 IE8 12 3.文本节点的内容:nodeValue
6.**元素属性:
1 所有的元素都有attribute属性,[i]访问每个属性--了解 2 读取属性:4中方法: 3 1.element.attribute[下标].value 4 2.var value=element.attribute["属性名"] 5 3.element.getAttributeNode("属性名").value 6 ***4.var value=element.getAttribute("属性名") 7 何时使用:只要获得任意属性的值 8 修改属性:2中: 9 ***1.element.setAttribute(name,value); 10 IE8不支持: 11 只能element.attribute["属性名"]=value; 12 2.element.setAttributeNode(attrNode); 13 移除属性:2种: 14 ***1.element.removeAttribute("属性名"); 15 2.element.removeAttributeNode(attrNode); 16 判断属性:2种 17 ***1.element.hasAttribute("属性名");//true/false 18 2.element.Attribute(attrNode); 19 20 Property vs Attribute 21 属性 特性 22 对象在内存中存储的属性 元素对象在开始标签中定义的html属性和自定义属性 23 24 访问html标准属性时,二者完全一致 25 比如:<a href="http://tmooc.cn"... 26 a.href-->属性 -->HTML DOM 27 a.getAttribute("href")-->特性 -->核心DOM 28 访问自定义属性时,二者不通用! 29 <li data-age="29">Ericli> 30 读取自定义属性:li.data-age X错 31 li.getAttribute("data-age"); 32 设置自定义属性:
7.元素样式:???
1 1.内联样式: 2 修改: elem.style.css属性名=”值”; 3 强调: css属性名必须去横线变驼峰 4 问题: elem.style.css属性名 一次只能修改一个属性,要修改的属性多时,代码会很繁琐 5 解决: 先将样式定义在class中,再用程序控制class 6 7 获取: elem.style.css属性名 只能获得内联样式 8 问题: 今后几乎没人写内联样式,很可能style什么样式也拿不到 9 解决: 获取计算后的样式 10 计算后的样式: 将最终应用到元素上的所有样式汇总到一起,并将相对单位的值计算为绝对单位值。 11 何时: 只要获取元素的样式,都必须用计算后的样式 12 如何: 2步: 13 1. 获得计算后的样式对象style 14 var style=getComputedStyle(elem); 15 2. 从style对象中提取想要的css属性值 16 var fontSize=style.fontSize; 17 强调: 计算后的样式都是只读,不可修改! 18 总结: 今后修改元素样式: elem.style… 19 获取元素样式: getComputedStyle() 20 2.内部/外部样式表:禁止修改
8.*创建和删除节点、常用的HTML DOM对象
1 1.*创建的删除节点 2 1.创建节点: 3 创建元素节点:3步 4 1.创建空元素对象: 5 var newElem=document.createElement("标签名"); 6 比如:var a=document.createElement("a"); 7 2.设置必要属性: 8 newElem.属性名="值"; 9 newELem.innerHTML="文本"; 10 比如:a.href="http://tmooc.cn"; 11 a.innerHTML="go to tmooc"; 12 <a href="http://tmooc.cn">go to tmooca> 13 3.将元素对象挂载到指定父元素下:2种: 14 追加:parent.appendChild(newElem); 15 强调:只有向已经在页面中的父元素追加新节点,才导致渲染 16 比如:div.appendChild(a); 17 <div> 18 …… 19 <a href="http://tmooc.cn">go to tmooca> 20 div> 21 2.创建文档片段:var frag=document.createDocumentfragment(); 22 DOM优化之一:尽量少的操作DOM树 23 页面加载过程: 24 html -> DOM Tree 25 ↓ 26 Render Tree -> *** layout *** -> paint 27 ↑ 计算每个元素 28 css -> CSS Model 的精确布局位置 29 在页面加载过程中,layout是复杂度最高,最耗时的操作。 30 只要出发页面样式的改变,都需要重新layout 31 所以,要尽量减少操作DOM树的次数! 32 如何: 33 1.如果同时添加父元素和子元素时,应该先在内存中将子元素拼都父元素中, 34 最后再整体一次性将父元素添加到页面——只出发一次layout 35 2.如果同时添加多个平级子元素时,用文档片段 36 文档片段: 内存中临时存储多个平级子元素的虚拟父元素 37 文档片段:内存中,临时存储多个子节点的存储空间 38 何时使用文档片段?反复追加多个平级元素 39 解决:先将所有平级元素追加到文档片段中 40 frag.appendChild(child) 41 将文档片段一次性追加到父元素下 42 parent.appendChild(frag) 43 *文档片段不参与追加*frag将子元素添加到页面后自动释放,不占页面内存
44 3. 插入新元素: 45 parent.insertBefore(newElem,oldElem); 46 删除节点:parent.removeChild(oldElem); 47 oldElem.parentNode.removeChild(oldElem);//自删 48 替换节点:parent.replaceChild(newElem,oldElem);
49 4.常用HTML DOM对象: 50 Table对象: 51 属性: 52 tHead tFoot tBodies 53 rows:获得表中所有行对象 54 rows[i]:获得表中小标为i的一个元素 55 方法: 56 var newRow=insertRow(rowIndex): 57 rowIndex写-1,表示在末尾追加 58 比如:insertRow(-1); 59 核心DOM:var newRow=document.createElement("tr"); 60 table.appendChild(newRow) 61 deleteRow(rowIndex): 62 比如:currRow.parentNode.removeChild(currRow); 63 table.deleteRow(currRow.rowIndex); 64 65 TableRow对象:代表table对象中的某一个tr对象 66 table.rows集合,就是一组TableRow对象的集合 67 属性: 68 cells:当前行中所有td对象 69 cells[i]:获得当前行中下标为i的td 70 rowIndex:当前行下标位置,专用于删除行 71 方法: 72 var newCell=insertCell(index) 73 比如:insertCell(3) 74 核心DOM:var td=document.createElement("td"); 75 tr.appendChild(td); 76 deleteCell(index) 77 Select对象: 78 属性: 79 options:获得当前select下所有option 80 options[i]:获得当前select下i位置的option 81 selectedIndex:获得当前选中的option 82 83 select.value 当前选中项的value,没有value,就返回选中项的内容 84 select.options 保存select下所有option元素对象 85 相当于: select.getElementsByTagName("option") 86 select.options.length 保存select下option的个数 87 清空select下所有option: select.options.length=0; 88 select.length 等效于select.options.length 89 清空select下所有option: select.length=0; 90 select.innerHTML=""; 91 select.selectedIndex 当前选中项的下标 92 93 事件 事件: onchange 当选中项发生改变时 94 95 方法: 96 select.add(薪option对象) 97 比如:select.appendChild(newOpt); 98 select.add(newOpt); 99 select.remove(index) 100 101 Option对象:指代select下的一个option元素 102 创建: 103 var newOpt=new Option(innerHTML,value); 104 创建option对象的同时,设置对象的innerHTML和value属性 105 相当于:var newOpt=document.createElement("option"); 106 newOpt.innerHTML="内容"; 107 newOpt.value="值" 108 一句话:创建,设置,追加 109 select.add(new Option(innerHTML,value)) 110 111 属性:index:获取当前option的下标位置,专用于删除 112 selected:可当做bool用 113 如果当前option被选中,返回true,否则false 114 From对象: 115 如何找到一个form对象 116 var form=document.forms[i/name]; 117 如何知道到form中的一个数据采集元素: 118 var elem=document.form.elements[i/name] 119 120 事件:onsubmit:在正式提交表单前自动触发 121 对整个表单执行验证 122 form.οnsubmit=function(){ 123 只要任意一个验证为通过,就*取消事件*:2步 124 1.获得event对象e" 125 var e=window.event||arguments[0]; 126 if(e.preventDefault){;//DOM 127 e.preventDefault(); 128 }else{ 129 e.returnValue=false; //IE8 130 } 131 132 让元素获得或失去焦点:elem.focus() 133 elem.blur() 134 获得、失去焦点的事件:onfocus/onblurs; 135 获得当前正在获得焦点的元素:document.activeElement 136 137 表单提交:2种:直接点submit按钮 138 如果当前form种任意元素获得焦点,按回车自动提交 139 只要自动表单提交前,先触发onsubmit
9.BOM
1 1.*BOM: 2 window对象: 3 ****定时器--动画 4 2.常用BOM对象: 5 ***Navigator 6 7 1.BOM:专门操作浏览器窗口的对象 8 window对象: 9 1.充当全局对象! 10 2.包含bom常用对象 11 属性: 12 大小于位置: 13 1.window.innerHeight/innerWidth:文档显示区的大小 14 outerHeight/outerWidth: 窗口的大小 15 pageXOffset/pafeYOffset: 文档左上角到文档显示区左上角的距离 16 17 2.screen.height/width: 桌面完整分辨率宽高 18 screen.availHeight/availWidth:去掉任务栏后剩余的宽高 19 20 3.调整大小:window.resizeTo(width,height) 21 调整到 22 resizeBy(变化的width,变化的height) 23 位置: 24 1.左上角x坐标:window.screenLeft||window.screenX; 25 y坐标:window.screenTop||window.screenY; 26 2.将窗口移动到指定坐标:window.moveTo(x,y) 27 3.事件发生时,鼠标的坐标(相对于整个屏幕):event.screenX|screenY 28 29 打开新连接:4种效果 30 1.在当前窗口打开新连接,可后退 31 html: <a href="url" target="_self">a> 32 js:[window].open("url","_self"); 33 2.在当前窗口打开新连接,禁止后退 34 js: location.replace("url"); 35 用新url代替history中当前url,结果: 无法后退 36 37 3.在新窗口打开新连接,可同时打开多个 38 html: <a href="url" target="_blank">a> 39 js: open("url","_blank") 40 41 4.在新窗口打开新连接,只能打开一个 42 target-->目标窗口的名称 43 _self:自动获得当前窗口名称 44 _blank:创建一个新窗口,随机生成一个不重复的名字 45 *窗口名:内存中打开新窗口会替换之前的窗口 46 47 html:<a href="xxx" target="自定义窗口名">a> 48 window.name="自定义窗口名" 49 js: open("url","自定义name属性值") 50 51 52 2.*定时器:让浏览器按指定时间间隔反复执行同一函数任务 53 2种: 54 周期性定时器:让浏览器按指定时间间隔反复执行同一任务,如果不手动停止,。。
一次性定时器:让浏览器等待一段时间间隔,执行一次任务自动停止。 55 在一次性定时器的结尾,每次重新启动一个一次性定时器 56 建议:尽量使用一次性代替周期性 57 如何使用:周期性和一次性用法完全相同 58 周期性:3件事: 59 1.动画的每一步要执行的任务(函数对象) 60 function step(){ 61 每一步要做的事情 62 } 63 2.将一步的任务放入定时器,反复调用 64 setInterval(step,间隔毫秒数) 65 3.必须用全局变量,临时存储定时器的编号 66 clearInterval(timer);timer=null; 67 一次性:3件事: 68 1.动画的每一步要执行的任务(函数对象) 69 function step(){ 70 每一步要做的事情 71 //根据条件判断是否有必要继续注册 72 } 73 2.讲一步的任务放入定时器,反复调用 74 timer=setTimeout(step,间隔毫秒数|等待毫秒数) 75 3.必须用全局变量,临时存储定时器的编号 76 clearTimeout(timer);timer=null;
10.常用BOM对象:navigator history location screen
1 1.navigator:保存浏览器配置信息的对象 2 cookieEnabled:判断当前浏览器是否启用cookie 3 plugins:保存所以插件对象的集合 4 userAgent:保存了浏览器名称,版本好的字符串 5 6 2.window常用子对象:history location screen 7 history:window对象中保存当前窗体访问过的URL历史记录栈 8 history.go(1):前进1次 9 -1:后退1次 10 2:前进2次 11 0:刷新 12 13 3.location: 14 location.search:获得URL中的查询字符串 15 如果进一步获得参数名和参数值? 16 先按&分割,再按=号分离 17 location.replace("新URL"):在当前窗口打开新连接,不可后退 18 (history中旧的URL被新的替换了) 19 使用location在当前窗口打开新连接:2中: 20 location.href="新URL"; 21 location.assign("新URL"); 22 刷新: 23 location.reload(); 24 25 4.screen:封装当前屏幕的显示信息 26 screen.height/width:完全屏幕宽高 27 availHeight/Width:去掉任务栏后的宽高
.***事件:
1 ***事件: 2 浏览器自动触发的或用户手动触发的对象状态的改变 3 DOM level2 Event标准 4 IE8:自成体系! 5 事件处理函数:当事件触发时,自动执行的函数 6 比如:<button onclick="函数/js语句">button> 7 8 事件处理: 9 1.事件定义(绑定事件处理函数)3种: 10 html:<标签 onxxx=""函数调用/js语句> 11 js:elem.onxxx=函数对象; 12 一个元素的事件处理函数,只能绑定一个函数对象 13 DOM标准:elem.addEventListener("事件名",函数对象,是否在捕获阶段触发 14 ) 一个元素的一个事件处理函数,可add多个不同函数对象 15 IE8:elem.attachEvent("on事件名",函数对象) 16 2.***事件周期:从浏览器捕获到事件后,一直到最后一个事件触发完,经历的过程。 17 DOM标准:3个阶段 18 1.(由外向内)捕获:从最外层html原素开始,向内逐层 19 记录每层原素绑定的事件处理函数。到目标元素为止 20 2.目标触发:自动执行目标元素上绑定的事件处理函数 21 3.(由内向外)事件冒泡:从目标元素的父级元素开始, 22 逐层向上执行每层的事件处理函数,到最外层html结束。 23 IE8的事件周期:2个阶段:没有捕获 24 3.event对象: 25 当事件发生时,自动创建,封装了事件信息(eg:keyCode screenX) 26 获得event对象: 27 html:οnclick="fun(event)" 28 实际调用时:event会自动获得当前事件对象 29 fun(e){ 30 e中获得的就是事件对象 31 } 32 js:elem.onxxx=fun; 33 fun(){ 34 //DOM标准:自动创建event对象,默认以第一个参数传入 35 //IE8:window全局的event属性,当事件发生时, 36 也会自动创建event对象,但会保存在window.event中 37 } 38 event对象中包含: 39 1.目标元素对象:var src=e.srcElement||e.target; 40 2.***取消/利用冒泡: 41 取消:DOM标准:e.stopPropagation() 42 IE8:e.cancelBubble=true; 43 一般用在当前事件处理结尾 44 ***优化:如果多个子元素中定义了相同的事件处理函数 45 其实,只需要在父元素上绑定一次,所有子元素即可共用 46 1. 获得目标元素: 47 不能用this, 因为this指父元素 48 应该用e.target,保存实际点击的目标元素 49 2. 鉴别目标元素: 50 先判断目标元素的nodeName或className... 51 只有目标元素符合要求时,才执行事件操作 52 53 3.*取消事件: 54 if(e.preventDefault){ 55 e.preventDefault();//DOM 56 }else{ 57 e.returnValue=false; 58 } 59 何时取消:比如:表单提交前,如果验证未通过,则取消 60 页面滚动: 61 事件: window.onscroll 62 获得页面滚动位置: document.body.scrollTop 63 页面超出文档显示区顶部的距离 64 65 事件坐标: 3对儿: 66 1. 相对于整个屏幕左上角的坐标: e.screenX|screenY 67 2. 相对于文档显示区左上角的坐标: e.clientX|clientY 68 3. 相对于当前元素左上角的坐标: e.offsetX|offsetY