JavaScript DOM
来源:互联网 发布:淘宝手绘照片是真的吗 编辑:程序博客网 时间:2024/05/23 11:15
一.什么是JavaScript DOM:
JavaScript DOM是Document Object Model for html(HTML 文档对象模型)的缩写。
解释下面几个概念:
A.文档:我们的html页面;
B.文档对象:页面中的元素;
C.文档对象模型:为了能够让程序中的JS去操作页面中的元素而定义的标准。把整个文档看成一棵树,数分枝就是节点,每个节点被定义为DOM节点,同时定义了很多方法来操作这些节点,如getElementById和document.body这些来获取节点的方法
二.DOM节点的常用属性:(后面无括号,且要写成 .XXX 的形式)
1.childNodes
:获取子节点列表集合,相当于用getElementsByTagName获取的节点集合
注意:A.不止元素节点是节点,节点类型共有12种。当获取一个父元素的childNodes时要比元素数量多,因为可能还会默认包含文本节点(一般为回车符)
B.用childNodes时会出现不兼容的情况:在IE下不会包含文本节点,在标准浏览器下会获取到包含文本节点的所有子元素节点
2.children
:同样是获取子节点列表集合,和childNodes作用对应,但与之不同的是,children可以解决上述的浏览器兼容性问题,原因是,children获取的子节点只包含元素节点
3.nodeType
:获取当前元素的节点类型,值为1代表元素节点,2代表属性节点,3代表文本节点
补充——属性节点:就是元素的属性
A.获取元素属性:元素.attributes
,例如:
<body><button id="btn">click</button><script> alert(document.getElementById('btn').attributes);</script></body>
B.获取属性的名称:元素.attributes[0].name
,例如:
<body><button id="btn">click</button><script> alert(document.getElementById('btn').attributes[0].name);</script></body>
C.获取属性的值:元素.attributes[0].value
,例如:
<body><button id="btn">click</button><script>alert(document.getElementById('btn').attributes[0].value);</script></body>
4.firstChild
:获取当前元素的第一个子节点:
注:A.获取到的子节点包含文本类型的节点,所以有浏览器兼容性问题。标准浏览器中的有效写法为:firstElementChild
B.因此,解决此问题的兼容写法应该为:
var oFirst = 元素.firstElementChild || 元素.firstChild;if(oFirst){ oFirst.style...//进行节点操作}
注:上述方法虽然已经是兼容性写法,但仍然会在元素没有子节点时出现问题。最好的办法就是父元素.children[0].style...
5.lastchild
:获取当前元素的最后一个子节点,存在兼容性问题,解决方法如下:
var oLast = 元素.lastElementChild || 元素.lastChild;if(oLast){ oLast.style...//进行节点操作}
6.nextSibling
:获取当前元素的下一个兄弟节点,存在存在兼容性问题,解决方法如下:
var oElemt = 元素.nextElementSibling || 元素.nextSibling;if(oElemt){ oElemt.style...//进行节点操作}
7.previousSibling
:获取当前元素的上一个兄弟节点,存在存在兼容性问题,解决方法如下:
var oElemt = 元素.previousElementSibling || 元素.previousSibling;if(oElemt){ oElemt.style...//进行节点操作}
8.parentNode
:获取当前元素的父节点。(父节点只有一个,因此没有兼容性问题)
9.offsetParent
:获取离当前最近的一个有定位属性的父元素节点。
注:存在兼容性问题如下:
如果没有距离当前元素有定位属性的父元素节点时:
A.在标准浏览器下,会默认为body
B.在IE7及以下浏览器中,若当前元素没有定位就是body,有定位就是html
10.offsetLeft/offsetTop
:获取当前元素到有定位属性的父元素的距离(偏移值)
注:存在兼容性问题如下:
A.在标准浏览器中,只要有定位属性的父级节点,left和top值就是相对于父级元素的距离;而其中如果有定位父级节点而元素本身无定位,在IE7及以下浏览器中指的是到body的距离;
B.如果没有定位父级元素,标准浏览器中是指到body的距离;而IE8及以下指的是到html的距离,而且他们的默认margin值不同,因此一定要提前清除默认样式
练习1:封装一个获取元素位置为getPosition
方法:
<style type="text/css">body{margin:0;}#div1{padding:40px 20px; background:#00F;}#div2{padding:40px 20px; background:#900; position:relative;}#div3{padding:40px 20px; background:#CF3;}</style><body><div id="div1"> <div id="div2"> <div id="div3"></div> </div></div><script> var oDiv1=document.getElementById("div1"); var oDiv2=document.getElementById("div2"); var oDiv3=document.getElementById("div3"); function getPosition(obj){ var json={'left':0,'top':0}; while(obj){ json.left+=obj.offsetLeft; json.top+=obj.offsetTop; obj=obj.offsetParent; } return json; }; alert(getPosition(oDiv3).top); alert(getPosition(oDiv3).left);
11.offsetWidth/offsetHeight
:获取的是盒子的宽、高值,无单位,可用于计算
注意:style.width/style.height获取的是元素style属性里的宽高,有单位,无法直接用于计算
三.操作元素属性的方法(方法后一般有括号)
1.获取元素属性值:元素.value和元素['value']
(带有变量的必须用[ ]),例如:
<body><img id="img" src="image/section1.jpg" /><script> alert(document.getElementById('img').src);</script></body>
2.获取元素的属性值:元素.getAttribute('属性名')
,例如:
<body><button id="btn">click</button><script> alert(document.getElementById('btn').getAttribute('id'));</script></body>
3.设置元素的属性值:元素.setAttribute('属性名','属性值')
,例如:
<body><button id="btn">click</button><script> document.getElementById('btn').setAttribute('style','background:red');</script></body>
4.删除元素属性值:元素.removeAttribute('属性名')
,例如:
<body><button id="btn">click</button><script>document.getElementById('btn').setAttribute('style','background:red');document.getElementById('btn').removeAttribute('style');</script></body>
对此模块的补充:
A.对于自定义属性的获取:用.
和[]
的方法可以在IE8及以下浏览器中取到自定义属性,但是在标准的浏览器下无法取到;用getAttribute()
可以在所有浏览器中取到自定义属性。
B.用.src
和['src']
的方法取到的是绝对路径,用getAttribute('src')
可以获取到相对路径(但IE7及以下不兼容,仍然是绝对路径)
四.元素的动态创建:
1.动态创建元素的优点:解决了innerHTML累加次数过多造成性能降低的问题;
2.创建元素,举例说明:
var oLi = document.createElement('li');
给创建的元素添加内容:
oLi.innerHTML = ...
3.在父级所有子元素中最后节点后添加元素:父级元素.appendChild(oLi)
4.在父级所有子元素中b节点前添加元素:父级元素.insertBefore(oLi,b)
5.在父级所有子元素中第一个节点前添加元素:父级.insertBefore(oLi,oUl,children[0])
注:存在兼容性问题,在IE中如果没有子元素就会报错,解决方法如下:
oUl.children[0]? oUl.insertBefore(oLi,oUl,children[0]):oUl.appendChild(oLi);
6.删除元素:父级元素.removeChild(oLi)
7.替换子节点:父级元素.replaceChild(新节点,被替换节点)
注:appendChild、insertBefore、replaceChild都是既可以操作动态创建的元素,也可以操作以有的元素,并且是剪切操作
练习2:做一个点击生成留言,要求最多只有5条留言,如果超出会将最早的留言删除
<style type="text/css">ul li{list-style:none;}#text1{width:500px; height:400px; border:1px #999 solid; float:left;}#btn1{cursor:pointer; float:left;}#ul1{width:500px; height:400px; border:1px #999 solid; float:left;}</style></head><body> <input type="text" id="text1" /> <button id="btn1">生成对话</button> <ul id="ul1"></ul> <script> var oText=document.getElementById("text1"); var oBtn=document.getElementById("btn1"); var oUl=document.getElementById("ul1"); var aLi=document.getElementsByTagName("li"); var num=0; oBtn.onclick=function(){ var oLi=document.createElement("li"); oLi.innerHTML = oText.value; oUl.appendChild(oLi); num++; if(num>5){ oUl.removeChild(aLi[0]); num--; } } </script></body>
效果如下:
练习3:将作业1里面的留言添加一个按钮-批量删除,要求留言有一个点击后背景变成黄色的效果(可以再次点击取消),然后点击批量删除时,删除所有背景颜色为黄色的留言
<style type="text/css">ul li{list-style:none;}#text1{width:500px; height:400px; border:1px #999 solid; float:left;}#btn1{cursor:pointer; float:left;}#ul1{width:500px; height:400px; border:1px #999 solid; float:left;}.col_yellow{background:yellow;}</style></head><body> <input type="text" id="text1" /> <button id="btn1">生成对话</button> <button id="btn2">批量删除</button> <ul id="ul1"></ul> <script> var oText=document.getElementById("text1"); var oBtn1=document.getElementById("btn1"); var oBtn2=document.getElementById("btn2"); var oUl=document.getElementById("ul1"); var aLi=document.getElementsByTagName("li"); oBtn1.onclick=function(){ var oLi=document.createElement("li"); oLi.innerHTML = oText.value; oUl.appendChild(oLi); for(var i=0;i<aLi.length;i++){ aLi[i].judge=true; aLi[i].onclick=function(){ if(this.judge){ this.style.backgroundColor='yellow'; this.judge=false; }else{ this.style.backgroundColor='white'; this.judge=true; } } } } oBtn2.onclick=function(){ for(var i=0;i<aLi.length;i++){ if(aLi[i].style.backgroundColor=='yellow'){//颜色其实不能用来做判断,在某些情况下可能会出错 oUl.removeChild(aLi[i]); i--;//如果不i--,导致相邻两个留言之间只能删除一个 } } } } </script></body>
效果如下:
四.HTML DOM className 属性
1.写一个函数funciton getElementsByClassName(),实现返回值为所传参数class类名的元素集合(该方法只能在标准浏览器中使用,ie浏览器中出错)
<body><div class="box box"></div><div class="box1"></div><div class="box box1"></div><ul id="ul1"> <li class="box"></li> <li class="box"></li> <li class="box1"></li> <p class="box"></p></ul><ul id="ul2"> <li class="box"></li> <li class="box1"></li> <li class="box1"></li></ul><script>var oUl = document.getElementById('ul1');function ByClass(parent,tagName,className){ var aEls = parent.getElementsByTagName(tagName); var arr = []; for(var i=0;i<aEls.length;i++){ var aClassName = aEls[i].className.split(' ');//避免当一个class中包含多个class不被选中的问题 for(var j=0;j<aClassName.length;j++){ if(aClassName[j] == className){ arr.push(aEls[i]); break;//避免<div class="box box"></div>此种情况重复选择的问题 } } } return arr;}alert(ByClass(oUl,'li','box').length);
2.为元素添加class:
A.首先要明确javascript没有直接给某元素添加类的addClass
方法,若需要给某个元素添加类属性时,需采用元素.className +='class名'
,例如:
<style> .color-red{background-color: red;}</style></head><body><button id="btn">click</button><script> document.getElementById('btn').className +='color-red';</script></body>
B.所以要想办法自己封装一个添加类的方法addClass
,如下:
function addClass( obj, className){ if( obj.className ==''){ obj.className = className; }else{ var arrClassName = obj.className.split(' '); if(arrIndexOf( arrClassName, className) ==-1){ obj.className += ' '+className; } //在已有的class名中判断,若没有就添加 }}function arrIndexOf(arr,v){ for(var i=0;i<arr.length;i++){ if(arr[i]==v){ return i; } } return -1;}
3.删除元素的class:
A.同样,javascript没有直接给某元素添加类的addClass
方法,若需要给某个元素添加类属性时,需采用元素.className =''
,例如:
<style> .color-red{background-color: red;}</style></head><body><button id="btn">click</button><script> document.getElementById('btn').className = '';</script></body>
B.那么同样也需要自己封装一个删除class的方法removeClass
,但是注意不能直接使用元素.className = ''
,因为会将所有的class都清空掉。如下:
function removeClass( obj, className){ if(obj.className !=''){ var arrClassName = obj.className.split(' '); if(arrIndexOf( arrClassName,className )!=-1 ){ arrClassName.splice(arrIndexOf( arrClassName,className ),1); obj.className = arrClassName.join(' '); } }}function arrIndexOf(arr,v){ for(var i=0;i<arr.length;i++){ if(arr[i]==v){ return i; } } return -1;}
练习4:将练习3的内容改成className操作完成
<style type="text/css">ul li{list-style:none;}#text1{width:500px; height:400px; border:1px #999 solid; float:left;}#btn1{cursor:pointer; float:left;}#ul1{width:500px; height:400px; border:1px #999 solid; float:left;}.col_yellow{background:yellow;}</style></head><body> <input type="text" id="text1" /> <button id="btn1">生成对话</button> <button id="btn2">批量删除</button> <ul id="ul1"></ul> <script> var oText=document.getElementById("text1"); var oBtn1=document.getElementById("btn1"); var oBtn2=document.getElementById("btn2"); var oUl=document.getElementById("ul1"); var aLi=document.getElementsByTagName("li"); oBtn1.onclick=function(){ var oLi=document.createElement("li"); oLi.innerHTML = oText.value; oUl.appendChild(oLi); for(var i=0;i<aLi.length;i++){ aLi[i].judge=true; aLi[i].onclick=function(){ if(this.judge){ this.className='col_yellow'; this.judge=false; }else{ this.className=''; this.judge=true; } } } } oBtn2.onclick=function(){ for(var i=0;i<aLi.length;i++){ if(aLi[i].className=='col_yellow'){ oUl.removeChild(aLi[i]); i--; } } } </script></body>
五.表格的DOM操作
1.浏览器在解析table的时候,会自动加一个tbody(表格正文)
, 这样直接通过表格元素.childred[1]
去获取tr的时候会出错,因此html里table最好直接加上thead和tbody
2.由于用children
去一级一级获取元素比较麻烦,JS提供了一些方法:tHead/tBodies/tFoot/rows/cells(表格头/表格正文/表格尾/行/列)
,例如,oTab.tBodies[0].rows[1].cells[1]
就可以获取到表格第一个正文中第二行第二列表格中元素
例如:
<table width="100%" id="table1" border="1" bordercolor="#000"> <thead> <tr> <th>1</th> <th>1</th> <th>1</th> <th>1</th> </tr> </thead> <tbody> <tr> <td>2</td> <td>2</td> <td>2</td> <td>2</td> </tr> <tr> <td>3</td> <td>3</td> <td>3</td> <td>3</td> </tr> <tr> <td>4</td> <td>4</td> <td>4</td> <td>4</td> </tr> </tbody></table><script>var oTab = document.getElementById('table1');oTab.tBodies[0].rows[1].cells[1].style.backgroundColor = 'red';</script></body>
注:一个表格里只能有一个表格头和尾,其他可以多个
练习5:用动创建元素的方法生成一个九九乘法表
<style>table{border-bottom:1px #999 solid; border-left:1px #999 solid; border-collapse:collapse;}td{border-right:1px #999 solid; border-top:1px #999 solid; padding:10px; text-align:center;}</style></head><body><!--<table id="table1"></table>--><script> //获取body标签 var oBody = document.getElementsByTagName("body")[0]; //创建一个<table>元素和一个<tbody>元素 var oTable=document.createElement('table'); var oTableBody = document.createElement("tbody"); for(var i=0;i<9;i++){ var row=document.createElement("tr"); for(j=0;j<=i;j++){ var col=document.createElement("td"); //创建一个文本节点 var oText = document.createTextNode((j+1)+'*'+(i+1)+'='+(j+1)*(i+1)); col.appendChild(oText); row.appendChild(col); } oTableBody.appendChild(row); oTable.appendChild(oTableBody); oBody.appendChild(oTable); }</script></body>
效果如下:
练习6:var data = [{},{},{},{}]; //写四个数据,里面包含id,username,sex和操作,并把它们动态添加到table里
要求:用DOM操作,隔行变色(白色灰色),操作为删除一行(删除后仍然隔行变色)
<style type="text/css">table{border:1px #000 solid; border-collapse:collapse;}tr{text-align:center;}td{width:150px; height:100px; border:1px #000 solid;}.background_white{background:#fff;}.background_gray{background:#ccc;}</style></head><body> <script> var data = [{'id':1,'username':'小一','sex':'男'},{'id':2,'username':'小二','sex':'女'},{'id':3,'username':'小三','sex':'男'},{'id':4,'username':'小四','sex':'女'}]; var num=0; var oTable=document.createElement("table"); var oTbody=document.createElement("tbody"); var aA=oTbody.getElementsByTagName("a"); var aTr=oTbody.getElementsByTagName("tr"); for(var i=0;i<data.length;i++){ var oTr=document.createElement("tr"); num++; if(num%2){ oTr.className='background_white'; }else{ oTr.className='background_gray'; } var dataJson=data[i]; for(var attr in dataJson){ var oTd=document.createElement("td"); oTd.innerHTML=dataJson[attr]; oTr.appendChild(oTd); } var oTd=document.createElement("td"); oTd.innerHTML+='<a href="javascript:;">删除</a>'; oTr.appendChild(oTd); oTbody.appendChild(oTr); for(var j=0;j<aA.length;j++){ aA[j].onclick=function(){ oTbody.removeChild(this.parentNode.parentNode); num--; for(var k=0;k<num;k++){ if(k%2){ aTr[k].className='background_gray'; }else{ aTr[k].className='background_white'; } } } } } oTable.appendChild(oTbody); document.body.appendChild(oTable); </script></body>
效果如下:
六.表单的DOM操作:
1.form里的元素中有个比id更重要的属性–name,而js也可以通过 oForm.name
值,就可以获取到这个元素,并且兼容所有浏览器
2.如果是单选和多选(name值相同为一组)时,用oForm.name值的方法获取的是一组元素,就不能直接控制了,可以循环来加事件
3.onchange
事件:当表单里的值发生变化时触发(表现为失去焦点时触发,但是如果值不变就不会触发),例如:
<body><input type="text" id="text" /><script> var oText = document.getElementById('text'); oText.onchange = function(){ alert("我的内容改变了!"); }</script></body>
效果如下:
往文本框里输入内容(表单获取焦点):
输完之后在空白处点击一下(文本框失去焦点,onchange事件被触发):
注:type = radio
标准浏览器点击时只要值变了就会触发,非标准(ie8及以下)下离开时才会触发
4.接下来的内容用下面这个例子说明表单的常用操作:
<select name='city'> <option value=''>请选择城市</option> <option value='北京'>北京</option> <option value='上海'>上海</option></select>
A.获取表单的值就是选择项的value值;
B.单选框、多选框和下拉框的选中状态:
元素.checked = true //被选中状态元素.checked = false //未被选中状态
练习7:对上述表单操作的练习:
<body><form id="form1" action="https://www.baidu.com/"> <input type="text" name="inp"/> <input type="button" name="click1" value="按钮"/> <input type="radio" name="sex"/>男 <input type="radio" name="sex" />女 <select name='city'> <option value=''>请选择城市</option> <option value='北京'>北京</option> <option value='上海'>上海</option> </select> <input type="submit" value="提交"/> <input type="reset" value="重置"/></form><script>var oForm = document.getElementById('form1');oForm.sex[0].checked = true;alert(oForm.sex.length);oForm.inp.onchange = function(){ alert(1234);}oForm.click1.onclick = function(){ alert(oForm.city.value);}oForm.onsubmit = function(){ if(oForm.inp.value==''||oForm.inp.value==' '){ alert('请输入内容'); return false; }}setTimeout(function(){ oForm.submit();},5000)oForm.onreset = function(){ if(!confirm('是否重置')){ return false; }}</script></body>
5.表单的事件和方法:
A.onsubmit
事件:当表单提交时,(点击submit时)
B.submit
方法:表单元素.submit()
,一般用于页面刷新时自动提交或自动延时提交表单等。
C.reset
事件:当表单重置的时候(点击reset时)
练习8:点击重置时让其确定,是否重置(用confirm()返回值,点击确定返回true,反之)
<body> <form id="form1" action="http://www.baidu.com"> <input type="text" name="text1" /> <input type="submit" value="提交" name="inp" /> <input type="reset" value="重置" /> </form> <script> var oForm=document.getElementById("form1"); oForm.onsubmit=function(){ if(oForm.text1.value==''){ alert("请输入内容!"); return false; }else{ oForm.submit(); } } oForm.onreset =function(){ if(!confirm("确定重置吗?")){ return false; } //用confirm来判断对浏览器弹框作出的选择,点击确定返回true,点击取消返回false } </script></body>
- [DOM]javascript DOM操作
- Javascript DOM
- javascript--dom
- JavaScript DOM
- Dom ,JavaScript
- Javascript DOM
- javascript Dom
- JavaScript DOM
- JavaScript Dom
- javascript-DOM
- Javascript -- DOM
- JavaScript/DOM
- JavaScript DOM
- JavaScript+DOM
- javascript dom
- javascript--DOM
- javascript DOM
- JavaScript DOM
- C语言邻接矩阵的实现
- 解决GitHub中灰色文件夹问题
- 时间飞逝,转眼已经快两年没更新博客了!
- 跳转指令
- 欢迎使用CSDN-markdown编辑器
- JavaScript DOM
- RecyclerView实现侧滑删除和拖拽排序
- C# 斐波那契数列
- 最小割树Gomory-Hu tree
- 剑指offer-面试题28-字符串的排列
- 谈浮躁
- 移动端Touch事件与H5-Canvas像素点检测实现刮刮乐
- 打砖块
- 数据库笔试题及答案