DOM( Document Object Model)
文档对象模型,通过 DOM 可以来任意来修改网页中各个内容
文档 :指的是网页,一个网页就是一个文档
对象 :指将网页中的每一个节点都转换为对象,转换完后,以一种纯面向对象的形式来操作网页
模型 :用来表示节点和节点之间的关系,方便操作页面
节点(Node) :构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点
常用的节点(每个节点的类型都不一样)
文档节点(Document) ,代表整个网页
元素节点(Element) ,代表网页中的标签
属性节点(Attribute) ,代表标签中的属性
文本节点(Text) ,代表网页中的文本内容
DOM 操作
DOM 查询
在网页中浏览器已经为我们提供了 document 对象,
它代表的是整个网页,它是 window 对象的属性,可以在页面中直接使用。
document 查询方法:
根据元素的 id 属性查询一个元素节点对象:
document.getElementById("id属性值")
根据元素的 name 属性值查询一组元素节点对象:
document.getElementsByName("name属性值")
根据标签名来查询一组元素节点对象:
document.getElementsByTagName("标签名")
获取页面中 html 根元素:
获取页面中的 body 元素:
根据元素的 class 属性值查询一组元素节点对象:
document.getElementsByClassName()
不支持 IE8 及以下的浏览器
返回文档中与指定选择器或选择器组匹配的第一个 Element 对象:
document.querySelector()
根据 CSS 选择器去页面中查询一个元素
IE8 使用 querySelector()代替
如果匹配到的元素有多个,那么它只会返回查询到的第一个元素
示例:var div = document.querySelector(“.box1 div”);
返回与指定的选择器组匹配的文档中的元素列表:
document.querySelectorAll()
根据 CSS 选择器去页面中查询一组元素
会将匹配到所有元素封装到一个数组中返回,即使只匹配到一个
具体的元素节点查询
元素.getElementsByTagName()
— 通过标签名查询当前元素的指定后代元素
元素.childNodes
— 获取当前元素的所有子节点,会获取到空白的文本子节点
元素.children
— 获取当前元素的所有子元素
元素.firstChild
— 获取当前元素的第一个子节点
元素.lastChild
— 获取当前元素的最后一个子节点
元素.parentNode
— 获取当前元素的父元素
元素.previousSibling
— 获取当前元素的前一个兄弟节点
元素.nextSibling
— 获取当前元素的后一个兄弟节点
innerHTML 和 innerText
两个属性作用类似,都可以获取到标签内部的内容,
不同是innerHTML会获取到html标签
,而innerText会自动去除标签
读取标签内部的文本内容
示例:<h1>h1中的文本内容</h1>
元素.firstChild.nodeValue
DOM 修改
document.createElement()
document.createTextNode()
父节点.appendChild(子节点)
父节点.insertBefore(新节点,旧节点)
父节点.replaceChild(新节点,旧节点)
父节点.removeChild(子节点)
删除指定的子节点
推荐方式:子节点.parentNode.removeChild(子节点)
元素的属性
使用 DOM 操作 CSS
修改
元素的样式 — 内联样式
语法:元素.style.样式名 = 样式值
注意:如果 CSS 的样式名中含有-,需要将这种样式名修改为驼峰命名法,aaBB
尽量不要为样式添加!important
读取
元素的样式 — 内联样式
读取
元素的当前显示的样式
正常浏览器 — 使用getComputedStyle()
这个方法是 window 对象的方法,可以返回一个对象,这个对象中保存着当前元素生效样式
可以通过对象.样式名来读取样式,如果获取的样式没有设置,则会获取到真实的值,而不是默认值
参数:
要获取样式的元素
可以传递一个伪元素,一般传 null
IE8
语法:元素.currentStyle.样式名
(IE 浏览器支持)
可以用来读取当前元素正在显示的样式,如果当前元素没有设置该样式,则获取它的默认值
定义一个函数,用来获取指定元素的当前的样式
参数
obj:要获取样式的元素
name:要获取的样式名
例子:
1 2 3 4 5 function getStyle (obj, name ) { return window .getComputedStyle ? getComputedStyle (obj, null )[name] : obj.currentStyle [name] }
clientWidth | clientHeight
这两个属性可以获取元素的可见宽度和高度,包括内容区和内边距
不带单位
offsetWidth | offsetHeight
获取元素的整个的宽度和高度,包括内容区、内边距和边框
offsetParent
可以用来获取当前元素的定位父元素
会获取到离当前元素最近的开启了定位的祖先元素
如果所有的祖先元素都没有开启定位,则返回 body
offsetLeft | offsetTop
scrollWidth | scrollHeight
scrollLeft | scrollTop
判断滚动条是否到底
垂直滚动条滚动到底:scrollHeight - scrollTop == clientHeight
水平滚动条滚动到底:scrollWidth - scrollLeft == clientWidth
元素.setCapture()
这个元素将会把下一次所有的鼠标按下相关的事件捕获到自身
上
事件(Event)
事件指的是用户和浏览器之间的交互行为。比如:点击按钮、关闭窗口、鼠标移动等
事件对象
当响应函数被调用时,浏览器每次都会将一个事件对象作为实参传递进响应函数中,这个事件对象中封装了当前事件的相关信息,比如:鼠标的坐标、按键,键盘的按键,滚轮的方向等
在响应函数中定义一个形参,来使用事件对象,但是在 IE8 及以下的浏览器中,是将事件对象作为 window 对象的属性保存的
解决事件对象的兼容性问题
1 2 3 元素.事件 = function (event ) { event = event || window .event }
clientX 可以获取鼠标指针的水平坐标,cilentY 可以获取鼠标指针的垂直坐标
获取滚动条滚动的距离
chrome 认为浏览器的滚动条是 body 的,可以通过 body.scrollTop 来获取
火狐等浏览器认为浏览器的滚动条是 html 的,
解决兼容问题:st = document.body.scrollTop || document.documentElement.scrollTop;
事件的冒泡(Bubble)
释义:指的是事件向上传导,当后代元素上的事件被触发时,将会导致其祖先元素上的同类事件也会触发。
如果需要取消冒泡,可以将事件对象的 cancelBubble 设置为 true
示例:
1 2 3 4 元素.事件 = function (event ) { event = event || window .event event.cancelBubble = true }
事件的委派
释义:指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素从而通过祖先元素的响应函数来处理事件。
事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
target — event 中的 target 表示的触发事件的对象
事件的绑定
使用 对象.事件 = 函数 的形式绑定响应函数,
只能同时为一个元素的一个事件绑定一个响应函数,
不能绑定多个,如果绑定了多个,则后边会覆盖掉前边的
绑定事件的方式:
可以在标签的事件属性中设置相应的 JS 代码(不建议 )
示例:<button onclick="js代码。。。">按钮</button>
可以通过为对象的指定事件属性设置回调函数的形式来处理事件
1 2 3 4 5 6 7 <button id="btn" >按钮</button> <script > var btn = document .getElementById ("btn" ); btn.onclick = function ( ){ alert ("你还点~~~" ); }; </script >
addEventListener()
— 不支持 IE8 及以下的浏览器
可以为元素绑定响应函数
参数:
事件的字符串,不要 on
回调函数,当事件触发时该函数会被调用
是否在捕获阶段触发事件,需要一个布尔值,一般都传 false
使用 addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,
这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
示例:
1 2 3 4 5 6 7 btn01.addEventListener ( 'click' , function ( ) { alert (1 ) }, false )
attachEvent()
在IE8
中可以使用 attachEvent()来绑定事件
参数:
事件的字符串,要 on
回调函数
这个方法也可以同时为一个事件绑定多个处理函数,
不同的是它是后绑定先执行,执行顺序和 addEventListener()相反
示例:
1 2 3 btn01.attachEvent ('onclick' , function ( ) { alert (1 ) })
定义一个函数,用来为指定元素绑定响应函数
addEventListener()中的 this,是绑定事件的对象
attachEvent()中的 this,是 window
需要统一两个方法 this
参数:
obj 要绑定事件的对象
eventStr 事件的字符串(不要 on)
callback 回调函数
示例:
1 2 3 4 5 6 7 8 9 10 11 12 function bind (obj, eventStr, callback ) { if (obj.addEventListener ) { obj.addEventListener (eventStr, callback, false ) } else { obj.attachEvent ('on' + eventStr, function ( ) { callback.call (obj) }) } }
事件的传播
微软认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件, 然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。
网景认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,然后在向内传播给后代元素
W3C 综合了两个公司的方案,将事件传播分成了三个阶段
捕获阶段
在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
目标阶段
事件捕获到目标元素,捕获结束开始在目标元素上触发事件
冒泡阶段
事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
如果希望在捕获阶段就触发事件,可以将 addEventListener()的第三个参数设置为 true
一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是 false
IE8 及以下的浏览器中没有捕获阶段
滚轮事件
onmousewheel 鼠标滚轮滚动的事件,会在滚轮滚动时触发,但是火狐不支持该属性
在火狐
中需要使用 DOMMouseScroll 且通过 addEventListener()来绑定滚动事件
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 box1.onmousewheel = function (event ) { event = event || window .event if (event.wheelDelta > 0 || event.detail < 0 ) { box1.style .height = box1.clientHeight - 10 + 'px' } else { box1.style .height = box1.clientHeight + 10 + 'px' } event.preventDefault && event.preventDefault () return false } bind (box1, 'DOMMouseScroll' , box1.onmousewheel )
键盘事件
onkeydown
— 按键被按下
对于 onkeydown 来说如果一直按着某个按键不松手,则事件会一直触发
当 onkeydown 连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快,这种设计是为了防止误操作的发生。
onkeyup
— 按键被松开
键盘事件一般都会绑定给一些可以获取到焦点的对象或者是 document
可以通过 keyCode 来获取按键的编码,通过它可以判断哪个按键被按下
altKey、ctrlKey、shiftKey
这个三个用来判断 alt、ctrl 和 shift 是否被按下,如果按下则返回 true,否则返回 false
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 document .onkeyup = function ( ) { console .log ('按键松开了' ) } input.onkeydown = function (event ) { event = event || window .event if (event.keyCode >= 48 && event.keyCode <= 57 ) { return false } }
拖拽事件
拖拽的流程
当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown
当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 window .onload = function ( ){ var box1 = document .getElementById ("box1" ); var box2 = document .getElementById ("box2" ); var img1 = document .getElementById ("img1" ); drag (box1); drag (box2); drag (img1); }; function drag (obj ){ obj.onmousedown = function (event ){ obj.setCapture && obj.setCapture (); event = event || window .event ; var ol = event.clientX - obj.offsetLeft ; var ot = event.clientY - obj.offsetTop ; document .onmousemove = function (event ){ event = event || window .event ; var left = event.clientX - ol; var top = event.clientY - ot; obj.style .left = left+"px" ; obj.style .top = top+"px" ; }; document .onmouseup = function ( ){ document .onmousemove = null ; document .onmouseup = null ; obj.releaseCapture && obj.releaseCapture (); }; return false ; };
文档的加载
浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行。
如果将 js 代码编写到页面的上边,当代码执行时,页面中的 DOM 对象还没有加载, 此时将会无法正常获取到 DOM 对象,导致 DOM 操作失败。
解决方式一:
可以将 js 代码编写到 body 里,放在最下边执行
示例:
1 2 3 4 5 6 <body> <button id ='btn' > 按钮</button > <script > var btn = document .getElementById ("btn" ); btn.onclick = function ( ){}; </script > </body>
解决方式二:
将 js 代码编写到 window.onload = function(){}中
window.onload 对应的回调函数会在整个页面加载完毕以后才执行, 所以可以确保代码执行时,DOM 对象已经加载完毕了
示例
1 2 3 4 5 6 <script> window .onload = function ( ){ var btn = document .getElementById ("btn" ); btn.onclick = function ( ){}; }; </script>
BOM
浏览器对象模型
BOM 可以使我们通过 JS 来操作浏览器,在 BOM 中提供了一组对象,用来完成对浏览器的操作
BOM 对象
Window
:代表的是整个浏览器的窗口,同时 window 也是网页中的全局对象
userAgent
:是一个字符串,通过这个字符串来判断不同的浏览器
火狐的 userAgent
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
Chrome 的 userAgent
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36
IE8-10
Mozilla/4.0 (compatible; MSIE 8/9/10.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
IE11
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko
注意:在IE11中已经将微软和IE相关的标识都已经去除了,所以我们基本已经不能通过UserAgent来识别一个浏览器是否是IE
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 if (/firefox/i .test (ua)) { alert ('你是火狐!!!' ) } else if (/chrome/i .test (ua)) { alert ('你是Chrome' ) } else if (/msie/i .test (ua)) { alert ('你是IE浏览器~~~' ) } else if ('ActiveXObject' in window ) { alert ('你是IE11,枪毙了你~~~' ) } if ('ActiveXObject' in window ) { alert ('你是IE,我已经抓住你了~~~' ) } else { alert ('你不是IE~~~' ) }
Location
:代表当前浏览器的地址栏信息,或者操作浏览器跳转页面
直接修改 location 属性,页面会自动跳转到该路径,并且会生成相应的历史记录
assign() — 用来跳转到其他的页面,作用和直接修改 location 一样
reload() — 用于重新加载当前页面,作用和刷新按钮一样
如果在方法中传递一个 true,作为参数,则会强制清空缓存刷新页面
示例:location.reload(true);
replace() — 可以使用一个新的页面替换当前页面,调用完毕也会跳转页面
不会生成历史记录,不能使用回退按钮回退
示例:location.replace(“01.BOM.html”);
History
:代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录
由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问时有效
length — 可以获取到当成访问的链接数量
back() — 可以用来回退到上一个页面,作用和浏览器的回退按钮一样
forward() — 可以跳转下一个页面,作用和浏览器的前进按钮一样
go() — 可以用来跳转到指定的页面
它需要一个整数作为参数
1:表示向前跳转一个页面 相当于 forward()
正整数:表示向前跳转 n 个页面
负整数:表示向后跳转 n 个页面
Screen:代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息
这些BOM对象在浏览器中都是作为window对象的属性保存的,可以通过window对象来使用,也可以直接使用