玩转JavaScript的Web API : 原生js操控显式HTML元素
之前做过两道前端,阿里和网易各一道。下文内容和解题的核心并无关系,只是当时想了解jQuery那么处理原生js的原理是什么,所以小结一下。
题目一:判断两个矩形元素是否重叠。
开始无尽的跑偏。。。。
Html元素都是HTMLElement实例,下例将div换成script、html都成立。
HTMLElement继承自Element,Element继承自Node。
定义一个长宽都是500px的红色div。
但是.style.height的方式获取不到高度值。如果使用style设置高度是有效的,再读取就是设置过的高度。
查看jQuery获取高度的方法,可发现这个属性: offsetHieght。offsetHieght是HTMLElement的只读属性,与此相似的还有Element的scrollHeight、clientHeight。运行以下代码可以理解它们之间的不同。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 <style> 7 #parent{ 8 width: 500px; 9 height: 500px; 10 background: red; 11 overflow: auto; 12 border: 5px; 13 padding: 5px; 14 margin: 5px; 15 } 16 #child{ 17 width: 800px; 18 height: 800px; 19 background: blue; 20 border: 5px; 21 padding: 5px; 22 margin: 5px; 23 } 24 </style> 25 26 </head> 27 <body> 28 <div id = 'parent'> 29 <div id = 'child'> 30 </div> 31 </div> 32 <button onclick='show()'>click</button> 33 <script> 34 var parent = document.querySelector('#parent'); 35 var child = document.querySelector('#child'); 36 37 //包含内边距和边框 38 console.log('offsetHeight'); //510 510 810 810 39 console.log(parent.offsetHeight); 40 console.log(parent.offsetWidth); 41 console.log(child.offsetHeight); 42 console.log(child.offsetWidth); 43 44 //取元素内容宽度和元素本身宽度更大者 45 console.log('scrollHeight'); //830 820 810 810 46 console.log(parent.scrollHeight); 47 console.log(parent.scrollWidth); 48 console.log(child.scrollHeight); 49 console.log(child.scrollWidth); 50 51 //只包含内边距,不包含滚动条、边框、外边距 52 console.log('clientHeight'); //493 493 810 810 53 console.log(parent.clientHeight); 54 console.log(parent.clientWidth); 55 console.log(child.clientHeight); 56 console.log(child.clientWidth); 57 58 function show(){ 59 //相对上一级的偏移 60 console.log('offsetTop'); //510 510 810 810 61 console.log(parent.offsetTop); 62 console.log(parent.offsetLeft); 63 console.log(child.offsetTop); 64 console.log(child.offsetLeft); 65 66 //滚动条卷进去的偏移 67 console.log('scrollTop'); //830 820 810 810 68 console.log(parent.scrollTop); 69 console.log(parent.scrollLeft); 70 console.log(child.scrollTop); 71 console.log(child.scrollLeft); 72 73 //边框的厚度 74 console.log('clientTop'); //493 493 810 810 75 console.log(parent.clientTop); 76 console.log(parent.clientLeft); 77 console.log(child.clientTop); 78 console.log(child.clientLeft); 79 } 80 81 </script> 82 </body> 83 </html>
跑偏完毕。
题目一的解答:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 <style> 7 #parent{ 8 width: 300px; 9 height: 300px; 10 margin-left: 100px; 11 } 12 #div1{ 13 width: 200px; 14 height: 200px; 15 background: red; 16 } 17 #div2{ 18 width: 300px; 19 height: 300px; 20 background: blue; 21 position: relative; 22 top: -200px; 23 } 24 </style> 25 </head> 26 <body> 27 <div id='parent'> 28 <div id = 'div1'> 29 </div> 30 </div> 31 <div id = 'div2'> 32 </div> 33 <script> 34 var div1 = document.querySelector('#div1'); 35 var div2 = document.querySelector('#div2'); 36 37 function isOverlap(e1,e2){ 38 var overlapX = false, 39 overlapY = false, 40 41 top1 = e1.offsetTop, 42 top2 = e2.offsetTop, 43 44 left1 = e1.offsetLeft, 45 left2 = e2.offsetLeft, 46 47 height1 = e1.offsetHeight, 48 height2 = e2.offsetHeight, 49 50 width1 = e1.offsetWidth, 51 width2 = e2.offsetWidth; 52 53 if(top1<top2 ){ 54 if(top1+height1>top2){ 55 overlapY = true; 56 } 57 } else { 58 if(top2+height2>top1){ 59 overlapY = true; 60 } 61 } 62 63 if(left1>left2 ){ 64 if(left1+width1>left2){ 65 overlapX = true; 66 } 67 } else { 68 if(left2+width2>left1){ 69 overlapX = true; 70 } 71 } 72 73 return overlapX && overlapY; 74 } 75 76 if(isOverlap(div2,div1)){ 77 alert('重叠了'); 78 } else { 79 alert('没重叠'); 80 } 81 82 </script> 83 </body> 84 </html>
题目二:可以说忘了吗^_^#,大致和通用事件注册,事件代理,列表选择有关。
这里我只关心如何改变一个div的样式。
Element的ClassName属性以字符串的形式保存拥有的class名称,多个class名空格隔开。
jQuery提供了addClass、removeClass、toggleClass操作元素的class。如果想使用原生js,并且通过类来改变div样式,难道必须进行字符串操作吗?
HTML5给Element带来一个新属性——classList,操作示例如下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 <style> 7 .size{ 8 width: 100px; 9 height: 100px; 10 } 11 .blue{ 12 background: blue; 13 } 14 .red{ 15 background: red; 16 } 17 </style> 18 </head> 19 <body> 20 <div class="size blue"> 21 </div> 22 <script> 23 var div = document.querySelector('div'); 24 console.log(div.className); //"size blue" 25 26 div.classList.add('red'); 27 console.log(div.className); //"size blue red" 28 29 div.classList.remove('red'); 30 console.log(div.className); //"size blue" 31 32 if(!div.classList.contains('red')){ 33 console.log('类已被移除'); 34 } 35 36 div.onclick = function(){ 37 div.classList.toggle('red'); 38 }; 39 </script> 40 </body> 41 </html>
随着越来越强大的新标准推行,原生js也简洁起来咯~