Python全栈开发之15、DOM
文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口。它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式。我们最为关心的是,DOM把网页和脚本以及其他的编程语言联系了起来。DOM属于浏览器,而不是JavaScript语言规范里的规定的核心内容。这里我们主要是讲用javascript操作DOM
一、查找元素
如果我们想用js操作文档,首先要做的便是要找到要操作的元素,查找元素有直接查找和间接查找,下面来看一下这两类查找,
// 直接查找 document.getElementById 根据ID获取一个标签 获取的是单个标签 document.getElementsByName 根据name属性获取标签集合 注意获取的是一个 ******数组******** document.getElementsByClassName 根据class属性获取标签集合 document.getElementsByTagName 根据标签名获取标签集合 // 间接查找 parentNode // 父节点 childNodes // 所有子节点 firstChild // 第一个子节点 lastChild // 最后一个子节点 nextSibling // 下一个兄弟节点 previousSibling // 上一个兄弟节点 parentElement // 父节点标签元素 children // 所有子标签 firstElementChild // 第一个子标签元素 lastElementChild // 最后一个子标签元素 nextElementtSibling // 下一个兄弟标签元素 previousElementSibling // 上一个兄弟标签元素
二、操作
1、内容
操作内容主要是 innerText,innerHTML和value其中前两种比较简单,主要是第三种在操作表单的时候,用得最多,text,password和textarea的value可以分为一类,checkbox,radio和select的value可以分为一类,下面来看下表单中操作value的例子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input id="i1" type="text" value="123"/> <input id="i2" type="password" value="111" /> <textarea id="i3">666</textarea> <h1>爱好</h1> <div id="i4"> <ul> <li> <input type="checkbox" value="1" /> 篮球 </li> <li> <input type="checkbox" value="2"/> 足球 </li> <li> <input type="checkbox" value="3"/> 去球 </li> </ul> </div> <div id="i5"> <ul> <li> <input type="radio" name="interesting" value="11" /> 篮球 </li> <li> <input type="radio" name="interesting" value="22"/> 足球 </li> <li> <input type="radio" name="interesting" value="33"/> 去球 </li> </ul> </div> <select id="i6"> <option value="11">上海</option> <option value="22">北京</option> </select> <script> // 下面三项的value值为用户输入的值,也可以通过value给其设置值 var vtext = document.getElementById('i1'); console.log(vtext.value); var vpasswd = document.getElementById('i2'); console.log(vpasswd.value); var vtextarea = document.getElementById('i3'); console.log(vtextarea.value); // 下面三项的 value 为选中后提交到后台value var vcheck = document.getElementById('i4'); var vli = vcheck.getElementsByTagName('input'); console.log(vli); vli[1].checked = true; //选中复选框的第二项 console.log(vli[1].value); //选中之后值为2 var vradio = document.getElementsByName('interesting'); console.log(vradio); vradio[1].checked = true; //选中单选框的第二项 console.log(vradio[1].value); var vselect = document.getElementById('i6'); console.log(vselect.value); // 默认为第一项上海,value为 11 var voption = vselect.children; //选中之后值为22 voption[1].selected = true; //选中第二项北京 </script> </body> </html>
下面再来看一个用单选框做的全选,反选,取消的小例子。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="btn"> <!--<input type="button" value="全选" onclick="SAll();">--> <!--<input type="button" value="反选" onclick="RAll();">--> <!--<input type="button" value="取消" onclick="CAll();">--> <input type="button" value="全选" onclick="Fun('S');"> <input type="button" value="反选" onclick="Fun('R');"> <input type="button" value="取消" onclick="Fun('C');"> </div> <div> <table> <thead> <tr> <th>序号</th> <th>用户名</th> <th>年龄</th> </tr> </thead> <tbody id="tb"> <tr> <td><input class="inp" type="radio" value="1"></td> <td>jason</td> <td>20</td> </tr> <tr> <td><input class="inp" type="radio" value="1"></td> <td>jason</td> <td>20</td> </tr> <tr> <td><input class="inp" type="radio" value="1"></td> <td>jason</td> <td>20</td> </tr> <tr> <td><input class="inp" type="radio" value="1"></td> <td>jason</td> <td>20</td> </tr> </tbody> </table> </div> <script> function SAll() { var tb = document.getElementById('tb'); var inp = tb.getElementsByTagName('input'); for(var i=0;i<inp.length;i++){ inp[i].checked = true; } } function CAll() { var tb = document.getElementById('tb'); var inp = tb.getElementsByClassName('inp'); for(var i=0;i<inp.length;i++){ inp[i].checked = false; } } function RAll() { var tb = document.getElementById('tb'); var inp = tb.getElementsByClassName('inp'); for(var i=0;i<inp.length;i++){ if(inp[i].checked){ inp[i].checked = false; } else{ inp[i].checked = true; } } } // 用一个函数加上switch函数解决 function Fun(arg) { var tb = document.getElementById('tb'); var inp = tb.getElementsByTagName('input'); switch(arg){ case 'S': for(var i=0;i<inp.length;i++){ inp[i].checked = true; } break; case 'C': for(var i=0;i<inp.length;i++){ inp[i].checked = false; } break; case 'R': for(var i=0;i<inp.length;i++){ if(inp[i].checked){ inp[i].checked = false; }else{ inp[i].checked = true; } } break; default: break; } } </script> </body> </html>
2、操作属性
除了操作内容,还可以操作标签属性,主要用到下面几个方法
attributes // 获取所有标签属性 setAttribute(key,value) // 设置标签属性 getAttribute(key) // 获取指定标签属性
下面来看一下示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="btn"> <input type="button" onclick="Func();" value="点击" /> <div id="i1" > <div class="c1" alex="gg" jason="hh">123</div> <div class="c1" alex="kk">123</div> <div class="c1">123</div> <div class="c1" alex="kk">123</div> <div class="c1" alex="kk">123</div> <div class="c1">123</div> <div class="c1" alex="kk">123</div> <div class="c1">123</div> </div> </div> <script> function Func() { var d = document.getElementById('i1'); var dchild = d.children; for(var i=0;i<dchild.length;i++){ if(dchild[i].getAttribute('alex')=='kk'){ dchild[i].innerText = 456; dchild[i].setAttribute('ko',666); // 设置属性 console.log(dchild[i].attributes); // 获取所有属性 } } } </script> </body> </html>
下面来看一个更加实用的小例子,点击不同的菜单显示不同的内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> *{ margin: 0; padding: 0; } .content{ margin: 0 auto; width: 300px; border: 1px solid chocolate; } ul{ list-style: none; background-color: #cccccc; } ul li{ float: left; display: block; background-color: #2459a2; padding:0 10px; height: 50px; line-height: 50px; cursor: pointer; } .clearfix:after{ display: block; content: ''; height: 0; visibility: hidden; clear: both; } #info{ min-height: 200px; width: 300px; } .hide{ display: none; } .active{ background-color: white; color: black; } </style> </head> <body> <div class="content"> <ul class="clearfix"> <li tg="1" class="active" onclick="Func(this)">价格走势</li> <li tg="2" onclick="Func(this)">市场分布</li> <li tg="3" onclick="Func(this)">其他</li> </ul> <div id="info"> <div targ="1" >conten1</div> <div targ="2" class="hide">conten2</div> <div targ="3" class="hide">conten3</div> </div> </div> <script> function Func(ths) { var bot = ths.parentElement.children; for(var i=0;i<bot.length;i++){ bot[i].classList.remove('active') } ths.classList.add('active'); var vtg = ths.getAttribute('tg'); var divs = document.getElementById('info').children; for(var i=0;i<divs.length;i++){ if(divs[i].getAttribute('targ') == vtg){ divs[i].classList.remove('hide'); }else{ divs[i].classList.add('hide'); } } } </script> </body> </html>
3、操作标签
下面主要演示一下如何操作标签,添加标签有两种方式,一种是以字符串,另外一种是以添加标签对象下面来简单的看一下例子,向列表中添加一项内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="btn"> <input type="text"> <input type="button" value="add" onclick="Addlist(this);"> </div> <h2 id="h">sss</h2> <div id="di"> <ul id="list"> <li>123</li> <li>123</li> <li>123</li> </ul> </div> <script> function Addlist(ths) { var v = ths.previousElementSibling.value; ths.previousElementSibling.value = ''; var li = document.getElementById('list'); //方式1 // var str= '<li>' + v +'</li>'; // li.insertAdjacentHTML('beforeEnd',str); var tag = document.createElement('li'); if(v.trim().length>0){ tag.innerText = v; li.appendChild(tag); li.insertBefore(tag,li.children[1]); } } var h = document.getElementById('h'); var d = document.getElementById('di'); var neh_h= h.cloneNode(true); // 不clone的话,以前的会移除 d.appendChild(neh_h); </script> </body> </html>
4、高度
高度主要有以下几种情况
- scrollTop: 滚动条距离顶部高度
- scrollHeight 文档高度:自身+padding
- clientTop 边框高度
- clientHeight 可见范围的高度:自身+padding
- offsetTop 当前标签距离“顶部”的高度
- 当前标签距离“上部”定位标签的高度
- offsetHeight 可见范围的高度:自身+padding+border
首先来看一个返回顶部的例子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .head{ height: 1500px; } .hide{ display: none; } #d1{ position: fixed; width: 40px; height: 40px; right: 20px; bottom: 20px; background-color: chocolate; color: white; } </style> </head> <body onscroll="F1();"> <div class="head"> <h1>he</h1> </div> <div id="d1" class="hide"> <a onclick="Func();">返回顶部</a> </div> <script> function Func() { document.body.scrollTop = 0; } function F1() { var h = document.body.scrollTop; var d = document.getElementById('d1'); if(h>100){ d.classList.remove('hide'); }else{ d.classList.add('hide'); } } </script> </body> </html>
下面在来看一个比较重要的布局,随着页面内容相应的菜单内容也跟着变化
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> *{ margin: 0; padding: 0; } .header{ height: 50px; width: 100%; background-color: black; } .menu{ position: absolute; min-height: 300px; background-color: azure; width: 200px; left:150px; } #article{ position: absolute; min-height: 700px; width: 700px; background-color: burlywood; left: 350px; } ul{ list-style: none; } ul li{ display: block; width: 100%; height: 40px; line-height: 40px; text-align: center; } #article .artc{ height: 900px; background-color: lavenderblush; } .fixed{ position: fixed; top: 0; } .active{ background-color: #2459a2; } </style> </head> <body onscroll="Hua();"> <div class="header"> </div> <div class="body"> <div class="content "> <div class="menu" id="menu"> <ul> <li>第一章</li> <li>第二章</li> <li>第三章</li> </ul> </div> <div id="article"> <div class="artc"> <p>content</p> </div> <div class="artc"> <p>sontent</p> </div> <div style="height: 300px" class="artc"> <p>sontent</p> </div> </div> </div> </div> <script> function Hua() { var huaHeight = document.body.scrollTop; var menu = document.getElementById('menu'); if(huaHeight>50){ menu.classList.add('fixed'); }else{ menu.classList.remove('fixed'); } var articles = document.getElementById('article').children; var menuitem = menu.getElementsByTagName('li'); for(var i=0;i<articles.length;i++){ var artofftop = articles[i].offsetTop; var artoffheight = articles[i].offsetHeight; // console.log(huaHeight,artofftop,artoffheight,i,clienthight); if(huaHeight-48>=artofftop){ for(var j=0;j<articles.length;j++){ menuitem[j].classList.remove('active') } menuitem[i].classList.add('active'); } } var clienthight =document.documentElement.clientHeight; if(huaHeight+clienthight == artofftop+artoffheight+50){ for(var j=0;j<articles.length;j++){ menuitem[j].classList.remove('active') } menuitem[articles.length-1].classList.add('active'); } } </script> </body> </html>
五、其他操作
document.geElementById('form').submit() //表单提交 console.log 输出框 alert 弹出框 confirm 确认框 // URL和刷新 location.href 获取URL location.href = "url" 重定向 location.reload() 重新加载 // 定时器 setInterval 多次定时器 clearInterval 清除多次定时器 setTimeout 单次定时器 clearTimeout 清除单次定时器
下面来看一下代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body > <input type="button" value="确出框" onclick="Confirm();"> <input type="button" value="定时器" onclick="Interval();"> <input type="button" value="取消定时器" onclick="Uninterval();"> <input type="button" value="单次定时器" onclick="Mytimeout();"> <input type="button" value="取消单次定时器" onclick="Unmytimeout();"> <div id="btns"> <input type="button" value="点我"> <input type="button" value="点我"> <input type="button" value="点我"> </div> <div id="i1"> </div> </body> <script> //location.href 获取URL //location.href = "url" 重定向 //location.reload() 重新加载 function Confirm() { var ret = confirm('xxxxxxx'); console.log(ret); } function f1() { console.log(123); } function Interval() { t1 = setInterval(f1,1000); // t1 = setInterval(function () { // console.log(2222) // },1000) } function Uninterval() { clearInterval(t1); } function Mytimeout() { document.getElementById('i1').innerText = 'xxxxxx'; t2 = setTimeout(function () { document.getElementById('i1').innerText = ''; },2000) } function Unmytimeout() { clearTimeout(t2); }
// 下面的代码是两个特殊的示例,需要特别的注意下 function f2() { for (var i=0;i<3;i++){ setInterval((function (arg) { //立即执行,函数没有返回值 console.log(arg); })(i),1000) } } f2(); var btns = document.getElementById('btns').children; for(var j=0;j<btns.length;j++){ btns[j].onclick = function () { alert(j); } } </script> </html>
六、事件
对于事件需要注意的要点:
- this
- event
- 事件链以及跳出
this标签当前正在操作的标签,event封装了当前事件的内容。