banner
banner
banner
NEWS LETTER

JS-DOM和事件

Scroll down

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 根元素:
    • document.documentElement
  • 获取页面中的 body 元素:
    • document.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
  • 读取元素的样式 — 内联样式
    • 语法:元素.style.样式名
  • 读取元素的当前显示的样式
    • 正常浏览器 — 使用getComputedStyle()
      • 这个方法是 window 对象的方法,可以返回一个对象,这个对象中保存着当前元素生效样式
      • 可以通过对象.样式名来读取样式,如果获取的样式没有设置,则会获取到真实的值,而不是默认值
      • 参数:
        1. 要获取样式的元素
        2. 可以传递一个伪元素,一般传 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 表示的触发事件的对象

事件的绑定

  • 使用 对象.事件 = 函数 的形式绑定响应函数,
  • 只能同时为一个元素的一个事件绑定一个响应函数,
  • 不能绑定多个,如果绑定了多个,则后边会覆盖掉前边的
  • 绑定事件的方式:
    1. 可以在标签的事件属性中设置相应的 JS 代码(不建议)
      • 示例:<button onclick="js代码。。。">按钮</button>
    2. 可以通过为对象的指定事件属性设置回调函数的形式来处理事件
      • 示例:
1
2
3
4
5
6
7
<button id="btn">按钮</button>
<script>
var btn = document.getElementById("btn");
btn.onclick = function(){
alert("你还点~~~");
};
</script>
  • addEventListener() — 不支持 IE8 及以下的浏览器
    • 可以为元素绑定响应函数
    • 参数:
      1. 事件的字符串,不要 on
      2. 回调函数,当事件触发时该函数会被调用
      3. 是否在捕获阶段触发事件,需要一个布尔值,一般都传 false
    • 使用 addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,
    • 这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
    • 示例:
1
2
3
4
5
6
7
btn01.addEventListener(
'click',
function () {
alert(1)
},
false
)
  • attachEvent()
    • IE8中可以使用 attachEvent()来绑定事件
    • 参数:
      1. 事件的字符串,要 on
      2. 回调函数
    • 这个方法也可以同时为一个事件绑定多个处理函数,
    • 不同的是它是后绑定先执行,执行顺序和 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 {
//IE8及以下
obj.attachEvent('on' + eventStr, function () {
//在匿名函数中调用回调函数
callback.call(obj)
})
}
}

事件的传播

  • 微软认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,
    然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。
  • 网景认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,然后在向内传播给后代元素
  • W3C 综合了两个公司的方案,将事件传播分成了三个阶段
    1. 捕获阶段
      • 在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
    2. 目标阶段
      • 事件捕获到目标元素,捕获结束开始在目标元素上触发事件
    3. 冒泡阶段
      • 事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
  • 如果希望在捕获阶段就触发事件,可以将 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
//event.wheelDelta 可以获取鼠标滚轮滚动的方向
//向上滚 120 向下滚 -120
//wheelDelta这个值不看大小,只看正负
//wheelDelta这个属性火狐中不支持
//在火狐中使用event.detail来获取滚动的方向
//向上滚 -3 向下滚 3
/*
* 当鼠标滚轮向下滚动时,box1变长
* 当滚轮向上滚动时,box1变短
*/
//判断鼠标滚轮滚动的方向
if (event.wheelDelta > 0 || event.detail < 0) {
//向上滚,box1变短
box1.style.height = box1.clientHeight - 10 + 'px'
} else {
//向下滚,box1变长
box1.style.height = box1.clientHeight + 10 + 'px'
}
/*
* 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
* 需要使用event来取消默认行为event.preventDefault();
* 但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错
*/
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
//数字 48 - 57
//使文本框中不能输入数字
if (event.keyCode >= 48 && event.keyCode <= 57) {
//在文本框中输入内容,属于onkeydown的默认行为
//如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
return false
}
}

拖拽事件

  • 拖拽的流程
    1. 当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown
    2. 当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
    3. 当鼠标松开时,被拖拽元素固定在当前位置 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");
//开启box1的拖拽
drag(box1);
//开启box2的
drag(box2);
drag(img1);
};
/*
* 提取一个专门用来设置拖拽的函数
* 参数:开启拖拽的元素
*/
function drag(obj){
obj.onmousedown = function(event){
// 设置box1捕获所有鼠标按下的事件
/*
* setCapture()
* - 只有IE支持,但是在火狐中调用时不会报错,而如果使用chrome调用,会报错
*/
obj.setCapture && obj.setCapture();
event = event || window.event;
// div的偏移量 鼠标.clentX - 元素.offsetLeft
// div的偏移量 鼠标.clentY - 元素.offsetTop
var ol = event.clientX - obj.offsetLeft;
var ot = event.clientY - obj.offsetTop;
// 为document绑定一个onmousemove事件
document.onmousemove = function(event){
event = event || window.event;
// 当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
// 获取鼠标的坐标
var left = event.clientX - ol;
var top = event.clientY - ot;
// 修改box1的位置
obj.style.left = left+"px";
obj.style.top = top+"px";
};
// 为document绑定一个鼠标松开事件
document.onmouseup = function(){
// 当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
// 取消document的onmousemove事件
document.onmousemove = null;
// 取消document的onmouseup事件
document.onmouseup = null;
// 当鼠标松开时,取消对事件的捕获
obj.releaseCapture && obj.releaseCapture();
};
/*
* 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,
* 此时会导致拖拽功能的异常,这个是浏览器提供的默认行为,
* 可以通过return false来取消默认行为,但是这招对IE8不起作用
*/
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,枪毙了你~~~')
}
// 如果通过UserAgent不能判断,还可以通过一些浏览器中特有的对象,来判断浏览器的信息
// 比如:ActiveXObject
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对象来使用,也可以直接使用
其他文章
cover
JS-正则表达式
  • 24/10/31
  • 11:05
  • JavaScript
cover
JS-工具函数和方法
  • 24/10/31
  • 11:05
  • JavaScript
目录导航 置顶
  1. 1. DOM( Document Object Model)
    1. 1.1. DOM 操作
      1. 1.1.1. document 查询方法:
      2. 1.1.2. 具体的元素节点查询
      3. 1.1.3. DOM 修改
      4. 1.1.4. 元素的属性
      5. 1.1.5. 使用 DOM 操作 CSS
  2. 2. 事件(Event)
    1. 2.1. 事件对象
    2. 2.2. 事件的冒泡(Bubble)
    3. 2.3. 事件的委派
    4. 2.4. 事件的绑定
    5. 2.5. 事件的传播
    6. 2.6. 滚轮事件
    7. 2.7. 键盘事件
    8. 2.8. 拖拽事件
  3. 3. 文档的加载
  4. 4. BOM
    1. 4.1. BOM 对象
请输入关键词进行搜索