类数组对象:arguments,nodeList
document.location对象:当前url信息
docuemnt.history对象:用户访问过的url信息
Object window Document的大小关系:
console.log(window.document); //#document
console.log(document.window); //undefined
Object: //JS中最大父类
//window:{} //页面中最大对象,整个浏览器
Node: //dom中最大父类
Document文档类
HTMLDocument ——实例对象 document,代表整个文档,每个网页都有自己的document对象
Element标签类 ——实例对象document.body,body里的标签类div,span
Comment注释类 ——实例对象document.body.firstChild
Text文本类
一、Node类——DOM中最大父类
JS中所有节点类型都继承自node类型,且共享相同的属性和方法
属性:nodeType:节点类型,返回值类型number(9,1,8,3)
nodeName:节点名字(document:#document)(标签类:大写字符串类型的标签名)
childNodes(nodeList):保存nodeList类数组对象,包含所有子节点,通过nodeList[下标]或nodeList.item(下标)访问
parentNode:父节点,在childNodes列表里所有节点都有相同父节点,每个节点之间是兄弟节点
先获取到当前节点,再获取当前节点的父节点
previousSibling::前一个兄弟节点(body的前一个,空白#text或head)
nextSibling:(body的)下一个兄弟节点(null)
firstChild:childNodes列表中的第一个节点(注意空白是#text)
lastChild:childNodes列表中的最后一个节点
ownerDocument:指向整个文档的节点,任何节点都属于它所在的文档
方法:hasChildNodes():包含子节点返回true
操作节点:都需要父节点对象进行调用!!
追加:appendChild(克隆/创建):childNodes末尾加一个节点——返回追加节点
插入:insertBefore(插入节点,参照节点)——返回插入节点(第二个参数是null,插到最后)插到参照节点前面
替换:replaceChild(新节点,旧节点)——返回替换节点
移除:removeChild(移除节点)——返回移除节点
其他方法:cloneNode(),创建副本 //只复制特定子节点
参数为true,深复制——复制节点本身和整个子节点
var clone=one.cloneNode(true);
为false(默认),浅复制——只复制节点本身
document.nodeType例子:console.log(document.nodeType);
console.log(document.body.nodeType);
结果:9
document.body is null //此时还没解析到body标签
nodeName例子:console.log(document.nodeName);
console.log(document.body.nodeName);
结果:#document
BODY
childNodes例子:console.log(document.body.childNodes);
body里:<div>div</div>
<span>span</span>
结果:NodeList(5) [ #text,div,#text,span,#text] //空白字符是#text
类数组对象(nodeList)——>数组对象,数组元素一样,只是{}变成[]——遍历,把每个类数组对象都拿出来
一、简单的笨方法:for循环
1>for循环,循环拿到每一个类数组对象中的数组元素
var childNodes=document.body.childNodes;
for(var i=0;i<childNodes.length;i++){
console.log(childNodes[i]);
}
body里也要写
2>声明一个空数组
3>把拿到的每一个类数组对象中的数组元素push到空数组中
二、切割:但切割是数组的方法——arr.slice.call(类数组对象),得声明一个数组
var childNodes=document.body.childNodes;
var arr=[1,2,3];
arr.slice.call(childNodes,切割的位置); //把切arr的地方换成childNodes,第二个参数不写或写0
slice的参数:回调函数和this
函数名.call(this,参数,参数...)
三、最简单方法(最常用)——Array.prototype.slice.call(类数组对象,切割的位置) //第二个参数不写或写0
var arr=Array.prototype.slice.call(childNodes,0);
追加appendChild()例子:
获取整个div的父类,因为追加需要父节点调用,TagName是标签名
获取四个按钮
获取第一个div——根据属性class
给第一个按钮绑定效果——点击第一个按钮追加第一个div
克隆第一个div
父节点对象调用追加函数
style:
给整个div的父类设置
分别给3个div设置
body:
父类,子类div
四个按钮
结果:点“追加”,就会多一个红的div1
二、Document文档类
属性、方法、子节点
document.×××()
通过属性/方法获取元素
属性://加[],返回HTMLCollection类数组对象(html元素集合)
images 获取所有img对象
forms 获取所有form对象
links 获取文档中所有带href属性的<a>元素
查找元素的方法:document.getElementById(),返回该元素或null,只返回第一次出现的
//加了s的都返回类数组对象
document.getElementsByName()——form表单时用过,向后台传值
document.getElementsByClassName(" " " "),包含所有指定的标识符才匹配
document.getElementsByTagName()——标签名
返回包含一个或多个元素的NodeList,在HTML文档中该方法返回的是HTMLCollection对象
与NodeList很类似,可通过[index/name],item(),namedItem(name)访问
document文档子节点,可以继承Node中所有属性和方法
documentElement 始终指向html页面中的<html>元素
body 指向<body>元素
doctype 访问<!DOCTYPE>, 浏览器支持不一致,很少使用
title 获取文档的标题
URL 取得完整URL
domain 取得域名,并且可以进行设置,在跨域访问中经常会用到。
referrer 取得链接到当前页面的那个页面的URL,即来源页面的URL
三、Element标签类
获取属性(公有属性、自定义属性)
获取节点(兄弟节点、子节点)
获取内容(含内部标签,光内容)
1、html元素
所有html元素都由HTMLElement类型或子类型表示
获取公有属性:通过.获取
style //返回对象
i //下面的都返回字符串类型的属性值
className 与元素class特性对应
title 附加说明信息
src,alt img元素的特有属性
获取自定义属性:
1)获取属性:getAttribute("属性名")
2)设置属性:setAttribute("属性名",属性值)如果该值存在——替换
3)移除属性:removeAttribute("属性值") ;
4)创建元素:document.createElement("div")
创建属性:document.createAttribute("flag").value='hello';
5)元素的子节点
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
其他浏览器 7个子节点(有文本节点)
2、获取节点——兄弟节点、子节点
将文档看做是Element树,只包含element标签类型,忽略Comment,Text节点
Element中的属性:children:类似于childNodes,返回nodeList类数组对象
firstElementChild:第一个孩子元素节点
lastElementChild
previousElementSibling:上一个兄弟元素节点
nextElementSibling:下一个兄弟元素节点
childElementCount:子标签数量,返回值=children.length
3、获取内容——设置后,标签被替换!
innerHTML 内部标签也可获取到(包括element、comment、text)
textContent 只解读普通文本(元素内容)
innerText ie浏览器(尽量忽略,兼容性差,逐渐不再开发人员的考虑范围之内)
四、Comment注释类+Text文本类
Comment类型:对注释操作很少,基本不会通过JS操作注释
Text类型:文本节点,包含可以按照字面解释的纯文本内容
length:文本长度
appendData(text):追加文本
deleteData(beginIndex,count):删除文本
insertData(beginIndex,text):插入文本
replaceData(beginIndex,count,text):替换文本
splitText(beiginIndex):将文本节点分成两个文本节点
substringData(beiginIndex,count):提取count个子字符串
document.createTextNode(要插入节点中的文本):创建文本节点
五、事件
事件对象、事件类型
例子:点击inner,一次弹出inner,center,outer
给dom2级事件设置第三个参数true,弹出次序相反
<style>
div#outer{
width:300px;
height: 300px;
border:1px solid black;
margin: 50px auto; /*上下50px,左右居中*/
}
div#center{
width:200px;
height: 200px;
border:1px solid black;
margin: 50px auto; /*上下50px,左右居中*/
}
div#inner{
width:100px;
height: 100px;
border:1px solid black;
margin: 50px auto; /*上下50px,左右居中*/
}
</style>
//获取三个元素
var outer=document.getElementById("outer");
var center=document.getElementById("center");
var inner=document.getElementById("inner");
//handler函数是弹框弹出outer
function handler(){
alert("outer");
}
//通过方法进事件绑定
outer.addEventListener("click",handler);
center.addEventListener("click",function(){alert("center")});
inner.addEventListener("click",function(){alert("inner");});
<body>
<div id="outer">outer
<div id="center">center
<div id="inner">inner</div>
</div>
</div>
</body>
5、事件对象,event方法preventDefault()例子
事件对象:当事件处理程序被调用时创建,window自动封装的对象event,保存触发事件处理程序时的一些细节
event.xxx type、target、currentTarget是event对象的属性,所以打印时event.×××
type:事件类型——在控制台会有事件类型
target:事件目标->指向最先触发的dom元素,保持不变
currentTarget:事件目标和this一样
this(可直接打印):当前哪个事件处理程序在执行,事件目标就指向当前绑定事件处理程序的dom对象
preventDefault(): 阻止事件的默认行为
stopPropagation():停止传播——W3C
cancelBubble=true; 取消冒泡——IE
例子:function handler(event){
console.log(event.type);
}
outer.addEventListener("click",handler);
<div id="outer">outer
<div id="center">center
<div id="inner">inner</div>
</div>
</div>
event方法preventDefault()例子:
<h1>签到</h1>
<form action="http://www.baidu.com">
学号:<input type="text" name="number">
<br>
<input type="submit" value="提交查询">
</form>
6、事件类型type
UI事件、焦点事件、鼠标与滚轮事件、相关元素(event特殊属性)、键盘与文本事件
1)UI(用户界面)事件:响应用户与元素的交互
load:页面完全加载后(包括外部资源)在window上触发
所有框架加载完毕时在框架集上触发
图像加载完毕时在img元素上触发
当嵌入内容加载完时在<object>元素上触发
unload:文档被完全卸载后触发,只要从一个页面切换到另一个页面就会发生onload事件
select:选择文本框(<input>,<textarea>)中的一个或多个字符时触发
resize:当浏览器窗口(window)被调整到一个新的高或宽时,会触发
scroll:当滚动带滚动条的元素内容时,在该元素上触发resize,scroll会在变化期间重复被激发
2)焦点事件
focus:获得焦点时触发,不支持冒泡
blur:失去焦点时触发
//IE支持
focusin:与focus等价,支持冒泡
focusout:与blur等价,支持冒泡
3)鼠标与滚轮事件
click:支持冒泡,点鼠标或按回车键时触发,只有在一个元素上相继发生mousedown,mouseup事件,才会触发click事件
dbclick:双击时触发
mousedown:任意位置
mouseup:松开鼠标
mousemove:在元素内部移动
mousewheel:滚轮事件
//常用
【支持子元素】
mouseover:移入
三个框:移到center时,outer(移到center时路过了outer),center,outer(再执行子元素)
mouseout:移出
【不支持子元素】,不冒泡
mouseenter:移入
三个框:移到center时,outer(移到center时路过了outer),center
mouseleave:移出
4)相关元素,event特殊属性
1.客户区坐标位置
clientX,clientY 事件发生时,鼠标指针在视口中位置
2.页面坐标位置
pageX,pageY 事件发生时,鼠标指针在页面本身(不是)视口的位置
页面没滚动时,pageX和pageY的值与clientX和clientY值相等
3.屏幕位置:screenX,screenY
4.修改键
值为boolean类型,用来判断对应的按键是否被按下
shiftKey
ctrlKey
altKey
metaKey
5.鼠标按钮
mousedown,mouseup,该事件的event对象中包含了button属性,表示按下或释放的按钮
0表示主鼠标按钮
1表示中间的滚动按钮
2表示次鼠标按钮
5)键盘与文本事件(文本框)——按了之后就进入文本框了
有一个keyCode值大全——就能知道用户按的是哪个键
keydown 按任意键触发,按住不放——重复触发
keypress 按字符键触发,按住不放——重复触发
keyup 松开键盘触发
当键盘事件发生时,event对象的keyCode属性中会包含一个代码与键盘上的特定键对应
对数字字母键,keyCode属性的值与ASCII码中对应的小写字母和数字编码相同
六、闭包
特点
基础闭包的例子
内部变量会被销毁的例子
按钮——外部变量不会被销毁的例子
闭包的特点:函数内部存在的函数
能访问闭包函数外部的变量—— 链式作用域
闭包使用的外部变量——会记住上一次的,不会被垃圾回收机制销毁——浪费内存
内部变量,会被销毁——每次都从最原始的开始
基础闭包的例子:function outer(){
var a=10;
return function(){
a++;
return a;
}
}
//在外侧拿到a
var result=outer(); //result是outer返回的函数
console.log(result()); //要的是函数里的返回值a
console.log(result()); //闭包使用的外部变量没被销毁
结果:11
12
内部变量会被销毁的例子:function outer(){
var a=10;
return function(){
var b=1;
console.log(++a);
console.log(++b);
}
}
//在外侧拿到a,b
var result=outer(); //result是outer返回的函数
result();
result();
result();
结果:11
2
12
2
13
2
//外部变量不会被销毁,拿的是最终i的值
例子:var btns=document.getElementsByTagName("button");
//五个按钮都当绑定事件后,才执行,此时都变成5了
for(var i=0;i<btns.length;i++){
btns[i].onclick=function(){
alert(i);
}
}
<button>button1</button>
<button>button2</button>
<button>button3</button>
<button>button4</button>
<button>button5</button>
结果:点击五个按钮,都返回5
点击五个按钮,依次显示0,1,2,3,4的例子:
//将原本声明的click右边函数 通过匿名函数的立即调用把参数传到匿名函数内部,让匿名函数保存参数
在内置闭包访问匿名函数外部的变量(匿名函数外部变量,不会被销毁)
var btns=document.getElementsByTagName("button");
for(var i=0;i<btns.length;i++){ //匿名函数的立即调用,立即执行
btns[i].onclick=(function(num){ //onclick右侧需要一个没被执行的函数声明(function)(i)
//第一次循环时,num是0
//第二次循环时,num是1
return function(){
alert(num);
}
})(i);
}
for(var i=0;i<btns.length;i++){
btns[i].onclick=(function(num){ onclick右侧:(function)(i)
return function(){alert(num)}
})(i);
}
<button>button1</button>
<button>button2</button>
<button>button3</button>
<button>button4</button>
<button>button5</button>
七、事件代理的例子(表格):点击“添加”按钮后,会添加一行
解决问题:动态添加的元素无法绑定事件的问题
方案:将本该绑定给子元素的事件,绑定给直接父元素(tr的直接父元素是tbody)
四种情况
结果:
事件代理的例子(表格):鼠标移入tr,控制台就会显示一个td
因为td把tr占满了,所以获取不到tr
事件代理的例子(表格):鼠标移入一行,那行就会变黄
法1:tr.style.backgroundColor=‘orange’; //直接改变了行内样式
法2:给tr设class
style里:.current{
background-color: orange;
}
js里:那句话改成:tr.className='current'; -----------最简单,Js和css代码完全分开,修改鼠标移入颜色更方便,不用动JS代码
或 tr.setAttribute('class','current');
事件代理的例子(表格):鼠标移出就恢复无色
JS里:
事件代理的例子(表格):新增的tr无色
trs里没有新增的tr