1.DOM介绍

DOM操作实现鼠标移上去变色
<ul><li img-data="0"></li><li img-data="0"></li></ul><script>var ul = document.getElementsByTagName("ul")[0];ul.onmouseover = function (e) {var e = e || window.event;var target = e.target || e.srcElement;target.style.backgroundColor = 'rgb(0,255,' + target.getAttribute('img-data') + ')';target.style.backgroundColor = 'rgb(0,255,' + target.setAttribute('img-data', target.getAttribute('img-data') + 100) + ')';}</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 所有子节点们 —>一个父节点有许多子节点(直接子节点) |
||
|---|---|---|
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

| | |
| —- | —- | —- |
|
|
// 找到所有元素节点var dv=document.getElementsByTagName('div')[0]// 找到所有的元素节点function returnElement(node){var temp={length:0,push:Array.prototype.push,splice:Array.prototype.splice}var child=node.childNodes,len=child.length;for(var i=0;i<len;i++){if(child[i].nodeType===1){temp.push(child[i])}}return temp;}console.log(returnElement(dv));
3.DOM结构树
3.1 练习

/*8---------------------------------------2----------------------------------------------8*/<div><p><ul><li><span><i></i></span></li></ul></p></div><script>function retPaerentNode(ele, n) {for (var i = 0; i < n; i++) {// 做一个兼容,当超出父节点范围,就返回nullele = ele && ele.parentElement;}return ele}var i = document.getElementsByTagName('i')[0];console.log(retPaerentNode(i, 1));/*8---------------------------------------4.----------------------------------------------8*///4.不能使用children,使用childNodes(找到直接子节点,不是子孙节点)Element.prototype.myChild = function () {var ele = this.childNodes;var arr = [];for (var i = 0; i < ele.length; i++) {if (ele[i].nodeType == 1) {arr.push(ele[i])}}console.log(arr);}var str = document.getElementsByTagName('strong')[0]console.log(str.childNodes);str.myChild()/*8-------------------------------------------------------------------------------------8*/function retAllChild(ele) {var no = ele.childNodes,arr = []for (var i = 0; i < no.length; i++) {if (no[i].nodeType == 1) {arr.push(no[i])}}return arr}var p = document.getElementsByTagName('p')[0];console.log(retAllChild(p));/*-------------------------------5.------------------------------------------------------*/// 5.hasChildNode()判断有元素没有元素节点function hasChild(ele) {var no = ele.childNodes;for (var i = 0; i < no.length; i++) {if (no[i].nodeType == 1) {return true}}return false}var strong = document.getElementsByTagName('strong')[0];console.log(hasChild(strong));/*------------------------3.封装返回兄弟节点的方法----------------------*/function retSbling(ele, n) {if (n > 0) {// 兼容一下,防止n超大时,求null的兄弟节点是错的while (ele && n) {if (ele.nextElementSibling) {ele = ele.nextElementSibling} else {//当浏览器不支持nextElementSibling,用下面的做兼容写法for (ele = ele.nextSibling; ele && ele.nodeType == 1; ele = ele.nextSibling);}n--}} else {while (ele && n) {if (ele.previousElementSibling) {ele = ele.previousElementSibling} else {for (ele = ele.previousSibling; ele && ele.nodeType == 1; ele = ele.previousSibling);}n++}}return ele}var strong = document.getElementsByTagName('strong')[0];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前面 | | |
| —- | —- | —- |
|
|
—————————>
<div style="width: 200px;height:200px ;background-color:pink;"></div><span>111</span>var divContent=document.getElementsByTagName('div')[0]var span=document.getElementsByTagName('span')[0]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. 注意:可以添加自定义的属性—->
| | | | —- | —- | —- | | |
<——>


<div><a href=""></a><p></p><span></span><i></i><b></b></div><script>Element.prototype.insertAfter=function(target){var nextElement=this.nextElementSibling;var parentNode=this.parentElement;if(nextElement && parentNode){parentNode.insertBefore(target,nextElement)}else{parentNode.appendChild(target)}}var p=document.getElementsByTagName('p')[0]var strong=document.createElement('strong')p.insertAfter(strong)/*实现标签的反转:从最后一个开始处理,遍历,依次把标签放到最后面*/function reverseElement(ele) {var child = ele.childNodes;for (var i = child.length-1; i>0 ; i--) {if (child[i].nodeType == 1) {var rever=ele.removeChild(child[i])ele.appendChild(rever)}}}var div = document.getElementsByTagName('div')[0];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

6. 注意:setInterval(‘console.log(“定时器”)’,1000);——>把字符串里面的代码当作JS代码来执行,每隔1s打印一次(定时器)
| | |
| —- | —- | —- |
|
|

minutes:<input value="0" type="text">seconds:<input value="0" type="text"></input><script>var input=document.getElementsByTagName('input');var m=input[0].value;var s=input[1].value;var timeId=setInterval(function(){s++;input[1].value=sif(s==60 && m!=3){m++;s=0;input[1].value=sinput[0].value=m}if(m==3){clearInterval(timeId)}},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 查看元素的几何尺寸
6.4 查看元素的尺寸和位置信息
注意:body有默认的8px,对于横向的8px会叠加,对于纵向的8px会重叠

1. offsetWidth/offsetWidth : 求元素宽高=border+padding+content(视觉尺寸)1. offsetLeft/offsetTop : 求元素的位置—>对于无定位的父级的元素,返回相对文档(document/body)的距离;对于有定位的父级的元素,返回相对有定位的父级的距离(不包括父级的border)—->不论该元素自身有没有定位1. domEle.offsetParent 求最近的有定位的父级 ,如果没有返回body;body.offsetParent=null1. 求元素相对于文档的坐标 |
||
|---|---|---|
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. 封装各个浏览器兼容的方法
| | |
| —- | —- | —- |
|
|
7.1 改变伪元素的样式
<style>div{width: 200px;height: 200px;background-color: pink;}.green::after{content:"";width: 100px;height: 100px;background-color: green;display: inline-block;}.red::after{content:"";width: 100px;height: 100px;background-color: red;display: inline-block;}</style></head><body><div class="green"></div><script>var div=document.getElementsByTagName('div')[0];// 点击改变伪元素的样式,一般情况下做不到,但通过改变类名可以做到div.onclick=function(){if(div.className=='green'){div.className='red'}else if(div.className=='red'){div.className='green'}}</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 事件处理函数例子(闭包解决)
<ul><li>0</li><li>1</li><li>2</li><li>3</li><li>4</li></ul><script>var liList=document.getElementsByTagName("li")for(var i=0;i<liList.length;i++){// 方法(1):注意一旦使用for循环的i,要考虑闭包问题(function(i){liList[i].addEventListener('click',function(){console.log(i);},false)})(i)//方法(2)// (function(i){// liList[i].onclick=function(){// console.log(i);// }// })(i)}</script>
8.2 事件处理函数的运行环境
8.3 事件处理函数的解除

//1.'onclick':只能执行一次的事件div.onclick=function(){console.log('执行');this.onclick=null;//解除了事件绑定}//2.'addEventListener':function(){}部分,绑定和解除必须是相同得liList[0].addEventListener('click',test,false)function test(){console.log("test");}liList[0].removeEventListener('click',test,false)//注意:这种方法无法解除,不是同一个函数了liList[0].addEventListener('click',function(){console.log("test");},false)liList[0].removeEventListener('click',function(){console.log("test");},false)//3.'attachEvent'同'addEventListener'用法相同
9.事件处理模型—(冒泡/捕获)

<div class="grandFather"><div class="father"><div class="son"></div></div></div><script>var grandFather = document.getElementsByClassName('grandFather')[0]var father = document.getElementsByClassName('father')[0]var son = document.getElementsByClassName('son')[0]// 1.事件冒泡:点击son-->fanther和grandFather也会打印(子元素冒泡到父元素)// grandFather.addEventListener('click',function(){// console.log("grandFather");// },false)// father.addEventListener('click',function(){// console.log("father");// },false)// son.addEventListener('click',function(){// console.log("son");// },false)// 1.事件捕获:(父元素捕获到子元素)grandFather.addEventListener('click',function(){console.log("grandFather");},true)father.addEventListener('click',function(){console.log("father");},true)son.addEventListener('click',function(){console.log("son");},true)
9.1 取消冒泡和阻止默认功能

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

<ul><li>1</li><li>2</li><li>3</li></ul><script>var ul = document.getElementsByTagName('ul')[0]ul.onclick = function (e) {var e = e || window.eventvar target = e.target || e.srcElementconsole.log(target.innerText);}</script>
9.4 实现鼠标拖拽效果
div {width: 100px;height: 100px;background-color: pink;position: absolute;left: 0;top: 0;}</style></head><body><div></div><script>var div = document.getElementsByTagName('div')[0];div.onmousedown = function () {document.onmousemove = function (e) {div.style.left = e.pageX - div.offsetWidth / 2 + 'px';div.style.top = e.pageY - div.offsetHeight / 2 + 'px';}div.onmouseup = function () {div.onmousemove = null}}
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(右键) | | |
| —- | —- | —- |
|
|
//判断左右键,只能使用document.onmousedown和onmouseup的事件参数e来判断,其他事件不可以document.onmousedown=function(e){if(e.button==0){console.log("左键");}else if(e.button==2){console.log("右键");}else{console.log("滚轮");}}
11.键盘事件
|
1. onkeydown > onkeypress > onkeyup (他们按下之后是连续触发的—->连续打印)
1. keydown :可以响应任意键盘按键, keypress :只可以响应字符类键盘按键
1. keypress : 返回ASCII码,可转换成相应的字符(有charCode即ASICC值)
String.fromCharCode(e.charCode) ASICC码值转为相应的字符 | | |
| —- | —- | —- |
|
|
12.文本操作事件
1. input.oninput 只要文本框里面的内容发生改变就触发1. input.onchange 只有文本框中内容改变,且获得焦点,并失去焦点的时候触发1. input.onfocus 获得焦点触发1. input.onblur 失去焦点触发 |
||
|---|---|---|
var input=document.getElementsByTagName('input')[0]input.oninput=function(){// 只要里面内容改变就触发console.log(this.value);}input.onchange=function(){// 只有文本框中内容改变,且获得焦点,并失去焦点的时候触发console.log(this.value);}//用onfocus和onblur来控制文本框中的内容(搜索文本)var input = document.getElementsByTagName('input')[0]input.onfocus = function () {if (this.value == "请输入") {this.value = ''}}input.onblur = function () {if (this.value == '') {this.value = '请输入'}}
13.窗体操作类(window上的事件)
|
1. window.onscroll=function(){console.log(window.pageYOffset)} 当滚动条一滚动就触发,
可获取滚动条距离X和Y的距离
2. window.onload
| | |
| —- | —- | —- |
|
|







