DOM
全称:Document Object Model 文档对象模型
JS中通过DOM来对HTML文档进行操作,理解了DOM就可以随心所欲的操作WEB页面
文档:文档表示的就是整个的HTML页面文档
对象:对象表示将页面中的每一个部分都转换为了一个对象
模型:使用模型来表示对象之间的关系,这样方便我们获取对象
节点
节点Node,是构成我们网页的最基本的组成部分,网页中的每一个部分都可以称为是一个节点。
节点的类型不同,属性和方法也都不尽相同
常用节点:
文档节点:整个HTML文档
元素节点:HTML文档中的HTML标签
属性节点:元素的属性
文本节点:HTML标签中的文本内容
节点的属性:
nodeName nodeType nodeValue
文档节点 #document 9 null
元素节点 标签名 1 null
属性节点 属性名 2 属性值
文本节点 #text 3 文本内容
注:
浏览器已经为我们提供 文档节点 对象,这个对象是window属性,可以在网页中直接使用,文档节点代表的是整个网页。document
获取到id=btn的button对象:
var btn = document.getElementByld("btn");
修改按钮的文字:
btn.innerHTML = "文字内容";
事件
事件,就是用户和浏览器之间的交互行为,比如:点击按钮,鼠标移动,关闭窗口
在事件对应的属性中设置一些js代码,当事件被触发时,这些代码将会执行。这种行为我们称为结构和行为耦合,不方便维护,不推荐使用
为按钮的对应事件绑定处理函数的形式来响应事件
var btn = document.getElementByld("btn");
btn.onclick = function(){
语句;
};
像这种为单击事件绑定的函数,我们称为单击响应函数
onload事件会在整个页面加载完成之后才触发
为window绑定一个onload事件,该事件对应的响应函数将会在页面加载完成之后执行,这样可以确保我们的代码执行时所有的DOM对象已经加载完毕了
window.onload = function(){
}
获取元素节点
通过document对象调用
1、getElementById() 通过id属性获取一个元素节点对象
2、getElementsByTagName() 通过标签名获取一组元素节点对象
3、getElementsByNam() 通过name属性获取一组元素节点对象
innerHTML用户获取元素内部的HTML代码
如果需要读取元素节点属性,直接使用 元素.属性名 (class不能使用这种方式)
读取class属性时需要使用 元素.className
获取元素节点的子节点
通过具体的元素节点调用
1、getElementsByTagName() -方法,返回当前节点的指定标签名后代节点
2、childNodes -属性,表示当前节点的所有子节点
3、firstChild -属性,表示当前节点的第一个子节点
4、lastChild -属性,表示当前节点的最后一个子节点
DOM查询
获取body标签
1、var body = document.getElementsByTagName("body")[0];
2、在 document中有一个属性body,它保存的是body的引用
var body = document.body
document.doocumentElement保存的是html根标签
var html = document.doocumentElement;
document.all代表页面中所有的元素
根据元素的class属性值查询一组元素节点对象
getElementsByClassName() 可以根据class属性值获取一组元素节点对象,但不支持ie8以下的浏览器(可以用querySelector()来代替)
var 属性值 = document.getElementsByClassName("属性值");
获取class为box1中的所有div
document.querySelector() 需要一个选择器的字符串作为参数,可以根据一个css选择器来查询一共元素节点对象
var div = document.querySelector(".box1 div");
使用该方法总会返回唯一的一个元素,如果满足条件的元素有多个,它只会返回第一个
document.querySelectorAll()
和querySelect()用法类似,不同的是它会将符合条件的元素封装到一个数组中返回。即使符合条件的元素只要一个,它也会返回数组
DOM增删改
创建元素节点
document.createElement()
可以创建一个元素节点对象,它需要一个标签名作为参数,将会根据该标签名创建元素节点对象,并将创建好的对象作为返回值返回
创建文本节点
document.createTextNode()
可以用来创建一个文本节点对象,它需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新的节点返回
把新的子节点添加到指定节点中
appendChild()
向一个父节点中添加一个新的子节点
用法: 父节点.appendChild(子节点);
在指定的子节点前面插入新的子节点
insertBefore()
可以在指定的子节点前插入新的子节点
用法: 父节点.insertBofore(新节点,旧节点);
替换子节点
replaceChild()
可以使用指定的子节点替换已有的子节点
用法: 父节点.replaceChild(新节点,旧节点);
删除子节点
removeChlid()
可以删除一个子节点
用法: removeChild(子节点);
子节点.parentNode可以获取子节点的父节点
innerHTML
也可以完成DOM的增删改的相关操作,两种方式结合使用
注:
点击超链接后,超链接会跳转页面,这个是超链接的默认行为。
但是我们此时不希望出现默认行为,可以通过在响应函数的最后return false来取消默认行为
或 <a href="javascript:;"></a>
confirm("")
//用于弹出一个带有确认和取消按钮的提示框,需要一个字符串作为参数,该字符串将会作为提示的内容
注:
for循环会在页面加载完成之后立即执行
而响应函数会在超链接被点击时才执行
当响应函数执行时,for循环早已执行完毕
DOM操作CSS样式及相关事件
通过JS修改元素的样式
语法:元素.style.样式名 = 样式值(字符串)
注意:如果css样式名中含有- 这种名称在JS中是不合法的,比如background-color,需要将这种样式名修改为驼峰命名法
去掉-,然后将-后的字母大写
注:
我们通过style属性设置的样式都是内联样式
而内联样式有较高的优先级,所以通过JS修改的样式往往会立即显示
但是如果在样式中写了!important,则此时样式会有最高的优先级,即使通过JS也不能覆盖该样式,此时将会导致JS修改样式失效。
读取样式
语法:元素.style.样式名
通过style属性设置和读取的都是内联样式,
无法读取样式表中的样式
读取元素当前样式
获取元素的当前显示的样式
语法:元素.currentStyle.样式名
它可以用来读取当前元素正在显示的样式
如果当前元素没有设置该样式,获取它的默认值
currentStyle只要IE浏览器支持,其他的浏览器都不支持
在其他浏览器中可以使用:
getComputedStyle() 这个方法来获取元素当前的样式,这个方法是window的方法,可以直接使用
需要两个参数:
1、要获取样式的元素
2、可以传递一个伪元素,一般都传null
该方法会返回一个对象,对象中封装了当前元素对应的样式
可以通过对象.样式名来读取样式,如果获取的样式没有设置,则会获取到真实的值,而不是默认值
该方法不支持ie8及以下浏览器
注:
通过currentStyle和getComputedStyle获取到的样式都是只读的,不可修改,修改只能通过style
其他样式操作的属性
clientWidth
clientHeight
可以获取元素的可见宽度和可见高度
这些属性都是不带px的,返回的都是一个数字,可以直接进行计算
会获取元素的宽度和高度,包括内容区和内边距
这些属性都是只读的,不能修改
offsetWidth
offsetHeight
获取对象的整个的宽度和高度,包括内容区、内边距和边框
foosetParent
可以用来获取当前元素的定位父元素
会获取到离我们当前元素最近的开启了定位的祖先元素
如果所有的祖先元素都没有开启定位,则返回body
offsetLeft
当前元素相对于其定位父元素的水平偏移量
offsetTop
当前元素相对于其定位父元素的垂直偏移量
clientHeight
获取元素滚动区域可见高度
scrollHeight
滚动区域整体高度
scrollWidth
滚动区域整体宽度
scrollLeft
可以获取水平滚动条滚动的距离
scrollTop
可以获取垂直滚动条滚动的距离
注:
当满足scrollHeight - scrollTop = clientHeight , 说明垂直滚动条滚动到底了
<!--如果为表单项添加disabled="disabled"则表单项将变成不可用的状态-->
/*disabled 属性可以设置一个元素是否禁用
*如果设置为true,则元素禁用
*如果设置为false,则元素可用
*/
事件对象
onscroll
//该事件会在元素的滚动条滚动时触发
onmousemove
该事件将会在鼠标在元素中移动时被触发
*事件对象
- 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数
- 在事件对象中封装了当前事件相关的一切信息,比如,鼠标的坐标,键盘哪个键按下 鼠标滚轮滚动的方向
clientX
可以获取鼠标的水平坐标
clientY
可以获取鼠标的垂直坐标
pageX
pageY
获取鼠标在相对页面的坐标
但是这两个属性在ie8中不支持,所以如果需要兼容ie8,不能使用
*在ie8中,响应函数被触发时,浏览器不会传递事件对象
*在ie8及以下的浏览器中,是将事件对象作为window对象的属性保存的
//解决事件对象兼容性问题
if(!event){
event=window.event;
}
或:event = event || window.event;
事件的冒泡
事件的冒泡(Bubble)
所谓的冒泡就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
在开发中大部分的冒泡都是有用的,如果不希望发生事件冒泡,可以通过事件对象来取消冒泡
//取消冒泡
//可以将事件对象的cancecanceBubble的值设置为true,即可取消冒泡
event.canceBubble = true;
事件的委派
我们希望,只绑定一次事件,即可应用到多个元素上,即使元素是后增加的
我们可以尝试将其绑定给元素的共同的祖先元素
事件的委派指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件
事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
如果触发事件的对象是我们期望的元素,则执行,否则不执行
if(event.target.className == "link(class名字"){ }
target
event中的target表示的是触发事件的对象
事件的绑定
使用 对象.事件 = 函数 的形式绑定响应函数
它只能同时为一个元素的一个事件绑定一个响应函数
不能绑定多个,如果绑定了多个,则后面会覆盖掉前面的
addEventListener()
通过这个方法也可以为元素绑定响应函数
使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
此方法不支持ie8及以下的浏览器
参数:
1、事件的字符串,不要on
2、回调函数(当事件触发时该函数会被调用)
3、是否在捕获阶段触发事件,需要一个布尔值,一般都穿false
例: btn01.addEventListener("click",function(){语句...},false);
attachEvent()
在ie8中可以使用attachEvent()来绑定事件
参数:
1、事件的字符串,要on
2、回调函数
这个方法也可以同时为一个事件绑定多个处理函数,不同的是它是后绑定先执行,执行顺序和addEventListener()相反
bind()函数
注:
addEventListener()中的this,是绑定事件的对象
attachEvent()中的this,是window
需要统一两个方法中的this
//定义一个函数,用来为指定元素绑定响应函数
参数:
obj 要绑定事件的对象
eventStr 事件的字符串(不要on)
callback 回调函数
function bind (obj,eventStr,callback){};
大部分浏览器兼容的方式
obj.addEventListener(eventStr,callback,false);
ie8及以下
obj.attachEvent("on"+eventStr,callback);
function bind (obj,eventStr,callback){ if(obj.addEventListener{ obj.addEventListener(eventStr,callback,false); }else{ /* *this是谁由调用方式决定 *callback.call(obj) */ obj.attachEvent("on"+eventStr,function(){ //在匿名函数中调用回调函数 callback.call(obj); }); } };
事件的传播
关于事件的传播,网景公司和微软公司由不同的理解
微软公司认为事件应该是由内向外传播的,也就是当事件触发时,应该先触发当前元素上的事件,然后再向当前元素的祖先元素上传播,也就是说事件应该在冒泡阶段执行
网景公司认为事件应该是由外向内传播的也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,然后再向内传播给后代元素
W3C综合了两个公司的方案,将事件的传播分成了三个阶段
1、捕获阶段
在捕获阶段时从最外层的祖先元素,向目标元素进行事件的的捕获,但是默认此时不会触发事件
2、目标阶段
事件捕获到目标元素,捕获结束开始在目标元素上触发事件
3、冒泡阶段
事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
一般情况下我们不会考虑在捕获阶段触发事件,所以这个参数一般都是false
ie8及以下的浏览器中没有捕获阶段
拖拽
拖拽的流程:
1、当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown
2、当鼠标移动时,被拖拽元素跟随鼠标移动 onmousemove
3、当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
当我们拖拽应该网页中的内容时,浏览器会默认去搜索引擎中搜索内容,此时会导致拖拽功能的异常,这个是浏览器提供的默认行为
如果不希望发生这个行为,则可以通过 return false;来取消行为
但是这招对ie8不起作用,
ie浏览器:
当调用一个元素的setCapture()方法以后,这个元素将会把下一次所有的鼠标按下相关的事件捕获到自身上
releseCapture()释放捕获
只有ie支持,但在火狐中调用不会报错,chrome中调用会报错
滚轮的事件
onwheel
鼠标滚轮滚动事件,会在滚轮滚动时触发,但火狐不支持该属性
wheelDelta可以获取鼠标滚轮滚动的方向
向上滚120 向下滚-120
wheelDelta 我们只看正负,不看大小
datail 火狐中使用event.datail来获取滚动方向,向上滚-3 向下滚3
当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动
这是浏览器的默认行为,如果 不希望发生,则可以取消默认行为。
return false;
使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
需要使用event来取消默认行为 event.preventDefault();
但是ie8不支持event.preventDefault();,如果直接调用会报错
键盘事件
onkeydown
按键被按下
对于onkeydown来说,如果一直按着一个按键不松手,事件会一直触发
当onkeydown连续触发时,第一次和第二次之间间隔会稍微长一点,其他的会非常的快。这种设计是为了防止误操作的发生
onkeyup
按键被松开
键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document
KeyCode
通过KeyCode来获取按键的编码,通过它可以判断哪个按键被按下
altKey
ctrlKey
shiftKey
判断alt crtl 和 shift是否被按下,如果按下返回true,否则返回false
在文本框中输入内容,属于onkeydown的默认行为,如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
BOM
浏览器对象模型
BOM可以使我们通过JS来操作浏览器
在BOM中为我们提供了一组对象,用来完成对浏览器的操作
BOM对象:
window
代表的是整个浏览器的窗口,同时window也是网页中的全局对象
Navigator
代表的是当前浏览器的信息,通过该对象可以来识别不同的浏览器
由于历史原因,Navigator对象中的大部分属性都已经不能帮我们识别浏览器了
一般我们只会使用userAgent来判断浏览器的信息
userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,不同的浏览器会有不同的userAgent
在ie11中已经将微软和ie相关的标识都已经去除了,所以基本上已经不能通过UserAgent来识别一个浏览器是否是ie了
如果通过UserAgent不能判断,还可以通过一些浏览器中特有的对象,来判断浏览器的信息,比如window.ActiveXObject
Location
代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
该对象中封装了浏览器的地址栏信息,如果直接打印Location,则可以获取到地址栏的信息(当前页面的完整路径)
如果直接将location属性修改为一个完整的路径,或相对路径,则我们页面会自动跳转到该路径,并且会生成相应的历史纪录
assign()
用来跳转到其他页面,作用和直接修改location一样
reload()
用于重新加载当前页面,作用和刷新按钮一样
如果在方法中传递一个true作为参数,则会强制清空缓存刷新页面
replace()
可以使用一个新的页面替换当前页面,调用完毕也会跳转页面
不会生成历史纪录,不能使用回退按钮回退
History
代表浏览器的历史纪录,可以通过该对象来操作浏览器的历史记录
由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页
而且该操作只在当次访问时有效
对象可以用来操作浏览器向前或向后翻页
history.length
该属性可以获取到当前访问的链接数量
history.back()
该方法可以用来回退到上一个页面,作用和浏览器回退按钮一样
history.forward()
该方法可以跳转到下一个页面,作用和浏览器前进按钮一样
history.go()
该方法可以用来跳转到指定的页面
它需要一个整数作为参数
1,向前跳转一个页面 相当于forward()
2,向前跳转两个页面
-1,向后跳转一个页面
Screen
代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关信息
注:
这些BOM对象在浏览器中都是作为window对象的属性保存的
可以通过window对象来使用,也可以直接使用
定时调用
如果希望一段程序,可以每间隔一段时间执行一次,可以使用定时调用
setTnterval()
定时调用,可以将一个函数,每隔一段时间执行一次
参数:
1、回调函数,该函数会每隔一段时间被调用一次
2、每次调用间隔的时间,单位是毫秒
返回值:返回一个Number类型的数据
这个数字用来作为定时器的唯一标识
setTnterval(function(){语句...},1000);
注:
绑定在单击响应函数中,每点击一次按钮,就会开启一个定时器
点击多次就会开启多个定时器,这就导致图片切换速度过快,并且我们只能关闭最后一次开启的定时器
在开启定时器之前,需要将当前元素上的其他定时器关闭
clearInterval()
可以用来关闭一个定时器
方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器
可以接收任意参数,如果参数是一个有效的定时器的标识,则停止对应的定时器,如果参数不是一个有效的标识,则什么也不做
延时调用
一个函数不马上执行,而是隔一段时间以后再执行,而且只会执行一次
延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次
setTimeout()
setTimeout(function, milliseconds)
在等待指定的毫秒数后执行函数。
clearTimeout()
关闭一个延时调用
注:
延时调用和定时调用实际上是可以互相代替的,开发中根据之间需要去选择
类的操作
通过style属性来修改元素的样式,每修改一个样式,浏览器就要重新渲染一次页面,这样执行的性能是比较差的,而且这种形式当我们要修改多个样式时,也不太方便
我们可以通过修改元素的class属性来间接的修改样式,这样一来我们只需要修改一次,即可同时修改多个样式,浏览器只需要重新渲染页面一次,性能比较好,并且这种方式可以使表现和行为进一步的分离
定义一个函数,用来向一个元素中添加指定的class属性值
参数:
obj 要添加class属性的元素
cn 要添加的class值
//判断一个元素中是否含有指定的class属性值 //如果有该class,则返回true,没有则返回false function hasClass(obj,cn){ //判断obj中有没有cn class //创建一个正则表达式 var reg = new RegExp("\\b"+cn+"\\b"); return reg.test(obj,className); } //定义一个函数,用来向一个元素中添加指定的class属性值 //参数: //obj 要添加class属性的元素 //cn 要添加的class值 function addClass(obj,cn){ if(!hasClass(obj,cn)){ obj.className +=" " +cn; } } //调用函数 addClass(box,"b2");
删除一个元素中指定的class属性
function removeClass(obj,cn){ //创建一个正则表达式 var reg = new RegExp("\\b"+cn+"\\b"); //删除class obj.className = obj.className.replace(reg,""); //删除box中的b2属性 removeClass(box,b2);
toggleClass可以用来切换一个类
如果元素中具有该类,则删除
如果元素中没有该类,则添加
function toggleClass(obj,cn){ //判断obj中是否含有cn if(function hasClass(obj,cn)){ //有,则删除 removeClass(obj,cn); }else{ //没有,则添加 addClass(obj,cn); } }
JSON
JS中的对象只有JS自己认识,其他语言都不认识
JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别,并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互
JSON
Javascript Object Notation JS对象表示法
JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号
其他的和JS语法一致
JSON分类
1、对象 { }
2、数组 [ ]
JSON中允许的值:
1、字符串
2、数值
3、布尔值
4、null
5、对象
6、数组
将JSON字符串转换为JS中的对象
在JS中,为我们提供了一个工具类,就叫JSON
这个对象可以帮助我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON
JSON.parse();
可以将一个JSON字符串转换为JS对象
需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回
JSON.stringify()
可以将一个JS对象转换为JSON字符串
需要一个JS对象作为参数,会返回一个JSON字符串
注:
JSON这个对象在ie7及以下的浏览器中不支持,在这些浏览器中调用会报错
eval()
这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回
如果使用eval()执行的字符串中含有 { },它会将 { } 当成是代码块
如果不希望将其当成代码块解析,则需要在字符串前后各加一个()
eval()这个函数的功能很强大, 可以直接执行一个字符串中的js代码,但是在开发中尽量不要使用,首先它的执行性能比较差,然后还具有安全隐患,
如果需要兼容ie7及以下浏览器的JSON操作,则可以通过引入外部js文件来处理