1.DOM介绍

image.png
DOM操作实现鼠标移上去变色

  1. <ul>
  2. <li img-data="0"></li>
  3. <li img-data="0"></li>
  4. </ul>
  5. <script>
  6. var ul = document.getElementsByTagName("ul")[0];
  7. ul.onmouseover = function (e) {
  8. var e = e || window.event;
  9. var target = e.target || e.srcElement;
  10. target.style.backgroundColor = 'rgb(0,255,' + target.getAttribute('img-data') + ')';
  11. target.style.backgroundColor = 'rgb(0,255,' + target.setAttribute('img-data', target.getAttribute(
  12. 'img-data') + 100) + ')';
  13. }
  14. </script>

2.DOM基本语法

注意:从DOM开始,一切生成的数组基本都为类数组,既是数组,又是对象,如果要操作,自己手动添加方法


1. document 代表整个文档,是标签的上面一层
1. getElementsByTagName 通过标签名获取,得到类数组
1. getElementsByClassName根据class类名来选择,不是所有浏览器都适用
1. querySelector("div>span /.div /#btn") 通过css选择器选择,选择一个
1. querySelectorAll() css选择器,选择一组 ——->不是实时的,选择后再增加或删除元素,还是之前选择出来的

2.1 遍历节点树


1. parentNode 父节点(最顶端的parentNode为#document) —>一个元素一个父节点
1. childNodes 所有子节点们 —>一个父节点有许多子节点(直接子节点)

image.png
image.png

2.2 结点的nodeName,nodeValue,nodeType

|
1. nodeName(只读):元素的标签名,以大写形式展示(文本节点nodeType=”#text”,注释节点nodeType=”#comment” 标签节点为1大写标签名”STRONG” document的nodeName=”#document”)
1. nodeValue(可读写):只有文本节点和注释节点有nodeValue,其他节点的nodeValue是null,
1. nodeType(只读):该节点的类型
1. attributes:属性节点的集合


1. hasChildNodes()判断有没有孩子节点,当且仅当
中间没有空格才为false
image.png
image.png | | | | —- | —- | —- | | |

  1. // 找到所有元素节点
  2. var dv=document.getElementsByTagName('div')[0]
  3. // 找到所有的元素节点
  4. function returnElement(node){
  5. var temp={
  6. length:0,
  7. push:Array.prototype.push,
  8. splice:Array.prototype.splice
  9. }
  10. var child=node.childNodes,len=child.length;
  11. for(var i=0;i<len;i++){
  12. if(child[i].nodeType===1){
  13. temp.push(child[i])
  14. }
  15. }
  16. return temp;
  17. }
  18. console.log(returnElement(dv));

3.DOM结构树

image.pngimage.png
image.png
image.png
image.png
image.png

3.1 练习

image.png

  1. /*8---------------------------------------2----------------------------------------------8*/
  2. <div>
  3. <p>
  4. <ul>
  5. <li>
  6. <span>
  7. <i></i>
  8. </span>
  9. </li>
  10. </ul>
  11. </p>
  12. </div>
  13. <script>
  14. function retPaerentNode(ele, n) {
  15. for (var i = 0; i < n; i++) {
  16. // 做一个兼容,当超出父节点范围,就返回null
  17. ele = ele && ele.parentElement;
  18. }
  19. return ele
  20. }
  21. var i = document.getElementsByTagName('i')[0];
  22. console.log(retPaerentNode(i, 1));
  23. /*8---------------------------------------4.----------------------------------------------8*/
  24. //4.不能使用children,使用childNodes(找到直接子节点,不是子孙节点)
  25. Element.prototype.myChild = function () {
  26. var ele = this.childNodes;
  27. var arr = [];
  28. for (var i = 0; i < ele.length; i++) {
  29. if (ele[i].nodeType == 1) {
  30. arr.push(ele[i])
  31. }
  32. }
  33. console.log(arr);
  34. }
  35. var str = document.getElementsByTagName('strong')[0]
  36. console.log(str.childNodes);
  37. str.myChild()
  38. /*8-------------------------------------------------------------------------------------8*/
  39. function retAllChild(ele) {
  40. var no = ele.childNodes,
  41. arr = []
  42. for (var i = 0; i < no.length; i++) {
  43. if (no[i].nodeType == 1) {
  44. arr.push(no[i])
  45. }
  46. }
  47. return arr
  48. }
  49. var p = document.getElementsByTagName('p')[0];
  50. console.log(retAllChild(p));
  51. /*-------------------------------5.------------------------------------------------------*/
  52. // 5.hasChildNode()判断有元素没有元素节点
  53. function hasChild(ele) {
  54. var no = ele.childNodes;
  55. for (var i = 0; i < no.length; i++) {
  56. if (no[i].nodeType == 1) {
  57. return true
  58. }
  59. }
  60. return false
  61. }
  62. var strong = document.getElementsByTagName('strong')[0];
  63. console.log(hasChild(strong));
  64. /*------------------------3.封装返回兄弟节点的方法----------------------*/
  65. function retSbling(ele, n) {
  66. if (n > 0) {
  67. // 兼容一下,防止n超大时,求null的兄弟节点是错的
  68. while (ele && n) {
  69. if (ele.nextElementSibling) {
  70. ele = ele.nextElementSibling
  71. } else {
  72. //当浏览器不支持nextElementSibling,用下面的做兼容写法
  73. for (ele = ele.nextSibling; ele && ele.nodeType == 1; ele = ele.nextSibling);
  74. }
  75. n--
  76. }
  77. } else {
  78. while (ele && n) {
  79. if (ele.previousElementSibling) {
  80. ele = ele.previousElementSibling
  81. } else {
  82. for (ele = ele.previousSibling; ele && ele.nodeType == 1; ele = ele.previousSibling);
  83. }
  84. n++
  85. }
  86. }
  87. return ele
  88. }
  89. var strong = document.getElementsByTagName('strong')[0];
  90. console.log(retSbling(strong, 100));

3.2 DOM基本操作

3.2.1 创建(元素)节点


1. document.createElement(“div”)增加元素节点
1. createTextNode(“文本”)增加文本节点
1. document.createComment(“注释”)增加注释节点

3.2.2 增加节点

|
1. 容器元素名.appendChild(元素名)——>类似于push()在末尾增加,但这是一个剪切操作,做完这个后原来位置的这个元素会消失
1. ParentNode.insertBefore(a,b): parentNode insert a before b
eg: divContent.insertBefore(text,span) 在divConent父容器里插入text,在span前面 | | | | —- | —- | —- | | |

image.png—————————>image.png

  1. <div style="width: 200px;height:200px ;background-color:pink;"></div>
  2. <span>111</span>
  3. var divContent=document.getElementsByTagName('div')[0]
  4. var span=document.getElementsByTagName('span')[0]
  5. divContent.appendChild(span)

3.2.3 删除节点

|
1. parent.removeChild():父节点,删除他的孩子节点——->返回值为删除的节点(剪切出来)
var sp=divContent.removeChild(span)
2. 当前节点.remove():自杀,没有返回值 span.remove()
| | | | —- | —- | —- | | |

3.2.4 替换节点

`parentNode.replaceChild(new ,old) 新的替换旧的,老的被剪切出了来

3.3 元素节点的属性和方法

| 属性:
1. innerHTML: 改变当前元素的内容(div.innerHTML取出div里面内容 div.innerHtml=’‘ 不是增加,是替换——->可以写标签,会读取标签并生成)
1. innerText:读取/改变当前元素的文本内容(赋值时是全覆盖,把其他元素覆盖,且赋值为元素时会被当作字符串,不会解析)
方法:
1. 元素名.setAttribute(‘属性名’,”属性值”)——>为元素设置属性
1. 元素名.getAttribute(‘属性名’)—————->获取元素属性值
1. 注意:可以动态为元素添加属性,从而实现动态添加样式的效果
1. 注意:可以添加自定义的属性—->


| | | | —- | —- | —- | | |

image.png <——>image.png
image.png

image.png

  1. <div>
  2. <a href=""></a>
  3. <p></p>
  4. <span></span>
  5. <i></i>
  6. <b></b>
  7. </div>
  8. <script>
  9. Element.prototype.insertAfter=function(target){
  10. var nextElement=this.nextElementSibling;
  11. var parentNode=this.parentElement;
  12. if(nextElement && parentNode){
  13. parentNode.insertBefore(target,nextElement)
  14. }else{
  15. parentNode.appendChild(target)
  16. }
  17. }
  18. var p=document.getElementsByTagName('p')[0]
  19. var strong=document.createElement('strong')
  20. p.insertAfter(strong)
  21. /*实现标签的反转:从最后一个开始处理,遍历,依次把标签放到最后面*/
  22. function reverseElement(ele) {
  23. var child = ele.childNodes;
  24. for (var i = child.length-1; i>0 ; i--) {
  25. if (child[i].nodeType == 1) {
  26. var rever=ele.removeChild(child[i])
  27. ele.appendChild(rever)
  28. }
  29. }
  30. }
  31. var div = document.getElementsByTagName('div')[0];
  32. reverseElement(div)

4.日期对象Date()


1. getDate() : 返回一个月(1-31)中的每一天
1. getDay() : 返回一周中的每一天(0-6)
1. getMonth() : 返回某一个月(0-11)—->真实的月份:getMonth()+1
1. getFullyear() : 以四位数字返回年份
1. getTime() : 返回1970年1月1日至今的毫秒数(获取事件戳)
1. date.setDate(1~31) :设置对象中月的某一天
1. date.setMonth(0~11)
1. date.setFullYear(四位数字)
1. date.setMilliseconds(0~999)
1. setTime() : 以毫秒设置Date对象
1. toString() 把Date时间转为字符串

5.定时器

|
1. 开启定时器(定时器是全局的Window):timeID=setInterval(function(){},1000);->每隔1000ms执行一次
1. 清除定时器: clearInterval(timeID)
1. 开启一次定时器:setTimeout(function() { },1000); 推迟作用,推迟一段时间执行,且只执行一次
1. 清除一次定时器:clearTimeout()
1. 注意 :定时器是全局对象 Window 上的方法,内部函数 this 指向 window
image.png
6. 注意:setInterval(‘console.log(“定时器”)’,1000);——>把字符串里面的代码当作JS代码来执行,每隔1s打印一次(定时器)

| | | | —- | —- | —- | | |

image.png

  1. minutes:<input value="0" type="text">
  2. seconds:<input value="0" type="text">
  3. </input>
  4. <script>
  5. var input=document.getElementsByTagName('input');
  6. var m=input[0].value;
  7. var s=input[1].value;
  8. var timeId=setInterval(function(){
  9. s++;
  10. input[1].value=s
  11. if(s==60 && m!=3){
  12. m++;
  13. s=0;
  14. input[1].value=s
  15. input[0].value=m
  16. }
  17. if(m==3){
  18. clearInterval(timeId)
  19. }
  20. },100)

6.DOM小操作(获取窗口属性,dom尺寸)

6.1 查看滚动条的滚动距离

|
1. 查看滚动条的滚动距离: window.pageXOffset window.pageYOffset (IE8及IE8以下不兼容)
1. 查看滚动条的滚动距离: document.body.scrollLeft/scrollTop
document.documentElement.scrollLeft/scrollTop
(IE8及IE8以使用,且两个相互冲突,一个有值,另一个位0)
解决: document.body.scrollTop+document.documentElement.scrollTop
console.log(window.pageYOffset);//229
console.log(document.body.scrollTop);//0
console.log(document.documentElement.scrollTop);//229 | | | | —- | —- | —- | | |

6.2 可视区窗口的尺寸

可视区窗口:我们能编写的html文档的部分—-》不包括控制台,url部分,标签栏部分

|
1. window.innerWith/innerHeight 浏览器内宽和高(IE8和IE8以下不兼容)
1. document.documentElement.clientWidth/clientHeight 标准模式下,任意浏览器都兼容
1. document.body.clientWith/clientHeight 怪异模式下的浏览器兼容
1. document.compatMode='BackCompat(怪异模式)'/'CSS1Compat(标准模式)' 用来判断当前浏览器是标准模式还是怪异模式
注意:
1. <!DOCTYPE html> 加上是标准渲染模式;不加上位怪异(混杂)模式,可以向后兼容浏览器版本(IE9可兼容IE8,IE7….)
| | | | —- | —- | —- | | |

6.3 查看元素的几何尺寸

image.png

6.4 查看元素的尺寸和位置信息

注意:body有默认的8px,对于横向的8px会叠加,对于纵向的8px会重叠
image.pngimage.png


1. offsetWidth/offsetWidth : 求元素宽高=border+padding+content(视觉尺寸)
1. offsetLeft/offsetTop : 求元素的位置—>对于无定位的父级的元素,返回相对文档(document/body)的距离;对于有定位的父级的元素,返回相对有定位的父级的距离(不包括父级的border)—->不论该元素自身有没有定位
1. domEle.offsetParent 求最近的有定位的父级 ,如果没有返回body;body.offsetParent=null
1. 求元素相对于文档的坐标

6.5 让滚动条滚动


1. window.scroll/scrollTo(距离x轴距离,距离y轴距离) 让滚动条滚动到相应位置—->刷新页面,滚动条不变,还是参数中要滚动的位置(不会在之前数据的基础上做累加)
1. window.scrollBy(距离x轴距离,距离y轴距离) 刷新页面会在上一次,滚动条滚动的位置进行叠加(会在之前数据的基础上做累加)

7.脚本化CSS

注意:只有xxx.style.xxx可写样式,其他的只能读取样式

|
1. 读写元素css的属性:style————>任何元素都有 xxx.style——>打印会返回一个样式表,可读写
注意:div.style.xxx——->读写的是行间样式,里面不能读取
2. 查询计算样式: window.getComputedStyle(元素,null) 获取当前元素展示的一切css的显示值
获取的是权重高的值—————————-》注意:他是只读的(IE8及以下不兼容),
返回的是计算过后的,单位是em是px,颜色red…也会换算位rgb(0,0,0)
3. 查询样式: ele.currentStyle.xxx/ele.currentStyle['xxx'] IE里面独有的方法,获取的是权重最高的值—->返回的不是计算过后的,单位是em就是em,颜色也不会换算位rgb
3. 封装各个浏览器兼容的方法
| | | | —- | —- | —- | | |

image.png

7.1 改变伪元素的样式

  1. <style>
  2. div{
  3. width: 200px;
  4. height: 200px;
  5. background-color: pink;
  6. }
  7. .green::after{
  8. content:"";
  9. width: 100px;
  10. height: 100px;
  11. background-color: green;
  12. display: inline-block;
  13. }
  14. .red::after{
  15. content:"";
  16. width: 100px;
  17. height: 100px;
  18. background-color: red;
  19. display: inline-block;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <div class="green"></div>
  25. <script>
  26. var div=document.getElementsByTagName('div')[0];
  27. // 点击改变伪元素的样式,一般情况下做不到,但通过改变类名可以做到
  28. div.onclick=function(){
  29. if(div.className=='green'){
  30. div.className='red'
  31. }else if(div.className=='red'){
  32. div.className='green'
  33. }
  34. }
  35. </script>

8.事件

| 绑定事件(事件处理函数):
1. ele.onxxx=function(){...} 一个元素只能绑定一个事件处理函数
1. ele.addEventListener(事件类型,function(){},false) IE9以下不兼容,可以绑定多个事件处理函数 —->IE9以下不兼容
eg: div.addEventListener('click',function (){console.log("11")},false)
也可以绑定多个: div.addEventListener('click',function(){},false); 按绑定的顺序执行
3. div.attachEvent('onclick',function(){}); IE独有,可以绑定多个事件处理函数
| | | | —- | —- | —- | | |

8.1 事件处理函数例子(闭包解决)

  1. <ul>
  2. <li>0</li>
  3. <li>1</li>
  4. <li>2</li>
  5. <li>3</li>
  6. <li>4</li>
  7. </ul>
  8. <script>
  9. var liList=document.getElementsByTagName("li")
  10. for(var i=0;i<liList.length;i++){
  11. // 方法(1):注意一旦使用for循环的i,要考虑闭包问题
  12. (function(i){
  13. liList[i].addEventListener('click',function(){
  14. console.log(i);
  15. },false)
  16. })(i)
  17. //方法(2)
  18. // (function(i){
  19. // liList[i].onclick=function(){
  20. // console.log(i);
  21. // }
  22. // })(i)
  23. }
  24. </script>

8.2 事件处理函数的运行环境

image.png

8.3 事件处理函数的解除

image.png

  1. //1.'onclick':只能执行一次的事件
  2. div.onclick=function(){
  3. console.log('执行');
  4. this.onclick=null;//解除了事件绑定
  5. }
  6. //2.'addEventListener':function(){}部分,绑定和解除必须是相同得
  7. liList[0].addEventListener('click',test,false)
  8. function test(){
  9. console.log("test");
  10. }
  11. liList[0].removeEventListener('click',test,false)
  12. //注意:这种方法无法解除,不是同一个函数了
  13. liList[0].addEventListener('click',function(){
  14. console.log("test");
  15. },false)
  16. liList[0].removeEventListener('click',function(){
  17. console.log("test");
  18. },false)
  19. //3.'attachEvent'同'addEventListener'用法相同

9.事件处理模型—(冒泡/捕获)

image.png

  1. <div class="grandFather">
  2. <div class="father">
  3. <div class="son"></div>
  4. </div>
  5. </div>
  6. <script>
  7. var grandFather = document.getElementsByClassName('grandFather')[0]
  8. var father = document.getElementsByClassName('father')[0]
  9. var son = document.getElementsByClassName('son')[0]
  10. // 1.事件冒泡:点击son-->fanther和grandFather也会打印(子元素冒泡到父元素)
  11. // grandFather.addEventListener('click',function(){
  12. // console.log("grandFather");
  13. // },false)
  14. // father.addEventListener('click',function(){
  15. // console.log("father");
  16. // },false)
  17. // son.addEventListener('click',function(){
  18. // console.log("son");
  19. // },false)
  20. // 1.事件捕获:(父元素捕获到子元素)
  21. grandFather.addEventListener('click',function(){
  22. console.log("grandFather");
  23. },true)
  24. father.addEventListener('click',function(){
  25. console.log("father");
  26. },true)
  27. son.addEventListener('click',function(){
  28. console.log("son");
  29. },true)

9.1 取消冒泡和阻止默认功能

image.png

  1. //1.取消事件冒泡:通过事件参数 >---> e
  2. son.addEventListener('click',function(e){
  3. console.log("son");
  4. //1.e.stopPropagation()--->W3C标准
  5. //2.e.cancelBubble=true--->IE独有(谷歌也有)
  6. },false)
  7. //2.阻止默认事件
  8. // 右键出现菜单的默认事件
  9. document.oncontextmenu=function(e){
  10. console.log("右击出菜单");
  11. // 阻止这个默认事件:右键不会再出现菜单,只会打印
  12. // 1. return false
  13. // 2. e.preventDefault()--->W3C标准
  14. e.returnValue=false//兼容IE
  15. }
  16. //3.取消a标签的跳转功能
  17. <a href="javascript:void(false)">杀杀杀</a>
  18. <a href="http://www.baidu.com" onclick="return false;">百度</a>

9.2 事件对象

image.png

9.3 事件委托

image.png

  1. <ul>
  2. <li>1</li>
  3. <li>2</li>
  4. <li>3</li>
  5. </ul>
  6. <script>
  7. var ul = document.getElementsByTagName('ul')[0]
  8. ul.onclick = function (e) {
  9. var e = e || window.event
  10. var target = e.target || e.srcElement
  11. console.log(target.innerText);
  12. }
  13. </script>

9.4 实现鼠标拖拽效果

  1. div {
  2. width: 100px;
  3. height: 100px;
  4. background-color: pink;
  5. position: absolute;
  6. left: 0;
  7. top: 0;
  8. }
  9. </style>
  10. </head>
  11. <body>
  12. <div></div>
  13. <script>
  14. var div = document.getElementsByTagName('div')[0];
  15. div.onmousedown = function () {
  16. document.onmousemove = function (e) {
  17. div.style.left = e.pageX - div.offsetWidth / 2 + 'px';
  18. div.style.top = e.pageY - div.offsetHeight / 2 + 'px';
  19. }
  20. div.onmouseup = function () {
  21. div.onmousemove = null
  22. }
  23. }

10.鼠标事件

|
1. onmousedown(鼠标按下)/onmouseup(鼠标弹起) / onmousemove(鼠标移动) ———————> click = onmousedown+onmouseup
1. document.oncontextmenu 右键唤起菜单(可以取消唤起菜单这个默认事件)
1. onmouseover(鼠标进入)/onmouseout(鼠标离开)
1. onmouseenter(鼠标进入)/onmouseleave(鼠标离开)
1. 如何判断左右键: `document.onmousedown/onmouseup=function(e){} 可通过事件处理参数e的
e.button==0(左键) e.button==1(滚轮) e.button==2(右键) | | | | —- | —- | —- | | |

  1. //判断左右键,只能使用document.onmousedown和onmouseup的事件参数e来判断,其他事件不可以
  2. document.onmousedown=function(e){
  3. if(e.button==0){
  4. console.log("左键");
  5. }else if(e.button==2){
  6. console.log("右键");
  7. }else{
  8. console.log("滚轮");
  9. }
  10. }

image.pngimage.png

11.键盘事件

|
1. onkeydown > onkeypress > onkeyup (他们按下之后是连续触发的—->连续打印)
1. keydown :可以响应任意键盘按键, keypress :只可以响应字符类键盘按键
1. keypress : 返回ASCII码,可转换成相应的字符(有charCode即ASICC值)
String.fromCharCode(e.charCode) ASICC码值转为相应的字符 | | | | —- | —- | —- | | |

image.png image.png

12.文本操作事件


1. input.oninput 只要文本框里面的内容发生改变就触发
1. input.onchange 只有文本框中内容改变,且获得焦点,并失去焦点的时候触发
1. input.onfocus 获得焦点触发
1. input.onblur 失去焦点触发
  1. var input=document.getElementsByTagName('input')[0]
  2. input.oninput=function(){
  3. // 只要里面内容改变就触发
  4. console.log(this.value);
  5. }
  6. input.onchange=function(){
  7. // 只有文本框中内容改变,且获得焦点,并失去焦点的时候触发
  8. console.log(this.value);
  9. }
  10. //用onfocus和onblur来控制文本框中的内容(搜索文本)
  11. var input = document.getElementsByTagName('input')[0]
  12. input.onfocus = function () {
  13. if (this.value == "请输入") {
  14. this.value = ''
  15. }
  16. }
  17. input.onblur = function () {
  18. if (this.value == '') {
  19. this.value = '请输入'
  20. }
  21. }

13.窗体操作类(window上的事件)

|
1. window.onscroll=function(){console.log(window.pageYOffset)} 当滚动条一滚动就触发,
可获取滚动条距离X和Y的距离
2. window.onload
| | | | —- | —- | —- | | |