JavaScript DOM
JS中通过操作DOM来对HTML文档进行操作
文档 - 整个HTML网页
对象 - 网页中的每一个部分都转换成了一个对象
模型 - 使用模型表示对象之间的关系
节点
网页中的每一个部分都可以称为是一个节点,但是具体类型是不同的
常用的四类节点:文档节点、元素节点、属性节点、文本节点
DOM基本操作
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
<button type="button" id="btn">我是一个按钮</button>
</body>
<script type="text/javascript">
var btn = document.getElementById("btn");
btn.innerHTML = "我不是";
</script>
</html>
事件
浏览器与用户之间的交互行为
我们可以在事件对于属性中设置一些js代码,当事件被处罚时,这些代码会执行
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
<button type="button" id="btn">我是一个按钮</button>
</body>
<script type="text/javascript">
// 获取按钮对象
var btn = document.getElementById("btn");
// 可以为按钮的对应事件绑定处理函数的形式来响应事件
// 这样当事件触发时,其对应的函数将会被调用
// 绑定一个单击事件
btn.onclick = function() {
alert('点点点');
}
</script>
</html>
文档的加载
浏览器加载页面时,按顺序加载,读取一行就运行一行,如果将 script 标签写到页面上边,在代码执行时,页面还没有加载
onload 事件会在整个页面加载完成之后才触发,可以为window绑定一个onload事件
- 该事件对应的响应函数将会在页面加载完成之后执行,这样可以确保我们的代码执行时所有的DOM对象已经加载完毕
DOM方法
获取元素节点
1.getElementById()
通过id属性获取一个元素节点对象
2.getElementsByTagName()
通过标签名获取一组元素节点对象
- 这个方法会给我们返回一个类数组对象,所有查询到的元素都会封装到对象中
3.getElementsByName()
通过name属性获取一组元素节点对象
4.getElementByClassName()
通过class属性获取一组元素节点对象
// 为id为btn01的按钮绑定一个单击响应函数
var btn01 = document.getElementById("btn01");
btn01.onclick = function() {
alert('hello');
};
innerHTML 用来获取元素内部的HTML代码,
对于自结束标签,没有意义,如果需要读取元素节点属性,直接使用 元素.属性名
读取class属性时需要使用 元素.className
DOM查询
获取元素节点的子节点
1.getElementsByTagName()
方法, 返回当前节点的指定标签名后代节点
2.childNodes
属性,表示当前节点的所有子节点
根据 DOM 标签,标签间的空白也会当成文本节点
children
属性,表示当前节点的所有子元素
3.firstChild/lastChild
属性,表示当前节点的第一个子节点/最后一个子节点
firstElementChild获取当前元素的第一个子元素
获取父节点和兄弟节点
1.parentNode
属性,表示当前节点的父节点
2.previousSibling/nextSibling
属性,表示当前节点的前一个兄弟节点/下一个兄弟节点
previousElementSibling
获取前一个兄弟元素
// 定义一个函数,专门用来为指定元素绑定单击响应函数
// 参数:idStr 要绑定单击响应函数的对象的id属性值
// fun 事件的回调函数,当单击元素时,该函数将会被触发
function myClick(idStr,fun) {
var btn = document.getElementById(idStr);
btn.onclick = fun;
}
myClick("btn07",function() {
var bj = document.getElementById("bj");
var pn = bj.parentNode;
});
innerHTML:用来获取元素内部的HTML代码(含标签)
innerText:获取到元素内部的文本内容(不含标签)
获取body标签:
var body = document.body;
document.querySelector()
需要一个选择器的字符串作为参数,可以根据一个CSS选择器来查询一个元素节点对象
var div = document.querySelector(".box1 div");
document.querySelectorAll()
总是返回数组
document.createElement()
可以用于创建一个元素节点对象,它需要一个标签名作为参数,将会根据该标签名创建元素节点对象,并将创建好的对象作为返回值返回
document.createTextNode()
可以用来创建一个文本节点对象,需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新的节点返回
appendChild()
向一个父节点中添加一个新的子节点
insertBefore()
可以在指定的子节点之前插入新的子节点
使用 innerHTML也可以完成 DOM增删改 的相关操作
一般结合使用
// 创建一个li
var li = document.createElement('li');
li.innerHTML = "广州";
// 将li添加到city中
city.appendChild(li);
DOM 操作内联样式
通过JS修改元素的样式
语法:元素.style.样式名 = 样式值
如果CSS的样式名中含有 - ,需要将这种样式名修改为驼峰命名法,去掉-,然后将 - 后的字母大写
我们通过style属性设置的样式都是内联样式
但是如果在样式中写了!important,则此时样式会有最高优先级,即使通过了JS也不能覆盖该样式,此时将会导致JS修改样式失效
通过style属性设置和读取的都是内联样式,无法读取样式表中的样式
获取元素的当前显示样式
语法: 元素.currentStyle.样式名
可以用来读取当前元素正在显示的样式
如果当前元素没有设置该样式,则获取它的默认值
currentStyle只有IE支持
在其他浏览器中可以使用 getComputedStyle()
这个方法来获取元素的样式
这个方法是window的方法,可以直接使用
需要2个参数:
- 1.要获取样式的元素
2.可以传递一个伪元素,一般传 null
该方法会返回一个对象,对象中封装了当前元素对应的样式
可以通过 对象.样式名
来读取样式
如果获取的样式没有设置,则会获取到真实的值,而不是默认值
// 处理浏览器兼容性问题
function getStyle(obj, name) {
if(window.getComputedStyle) {
// 正常浏览器的方式,具有getComputedStyle()方法
return getComputedStyle(obj, null)[name];
}else{
// IE8的方式,没有getComputedStyle()方法
return obj.currentStyle[name];
}
}
onmousemove
该事件将会在鼠标在元素中移动时被触发
事件对象 DOM event
当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数,
在事件对象中封装了当前时间相关的一切信息,比如:鼠标的坐标,键盘哪个按键被按下,鼠标滚轮滚动的方向
clientX
可以获取鼠标指针的水平坐标
clientY
可以获取鼠标指针的垂直坐标
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<style type="text/css">
#areaDiv {
width: 200px;
height: 200px;
border: 1px solid black;
}
</style>
</head>
<body>
<div id="areaDiv"></div>
<div id="showMsg"></div>
</body>
<script type="text/javascript">
var areaDiv = document.getElementById("areaDiv");
var showMsg = document.getElementById("showMsg");
areaDiv.onmousemove = function(event) {
// 在showMsg显示鼠标的坐标
var x = event.clientX;
var y = event.clientY;
showMsg.innerHTML = "x = "+x + ", y = "+y;
}
</script>
</html>
div 跟随鼠标移动
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<style type="text/css">
#box1 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div id="box1"></div>
</body>
<script type="text/javascript">
var box1 = document.getElementById("box1");
document.onmousemove = function(event) {
var left = event.pageX;
var top = event.pageY;
// 设置div的偏移量
box1.style.left = left + 'px';
box1.style.top = top + 'px';
}
</script>
</html>
事件的冒泡
事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
如果不希望发生事件冒泡,可以通过事件对象来取消冒泡
// 为body绑定一个单击响应函数
document.body.onclick = function() {
event.cancelBubble = true;
}
事件的委派
将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件
事件委派是利用了冒泡,通过冒泡可以减少事件绑定的次数,提高程序性能
事件给谁绑定的, this就是谁
event中的target表示的是触发事件的对象
事件的绑定
使用 对象.事件 = 函数
的形式绑定响应函数,只能同时为一个元素的一个事件绑定一个响应函数,不能绑定多个,后面的会覆盖前面的
通过 addEventListener()
也可以为元素绑定响应函数
参数:
1.事件的字符串,不要on
2.回调函数,当事件触发时,该函数会被调用
3.是否在捕获阶段触发事件,需要一个布尔值,一般都穿false
使用 addEventListener() 可以同时为一个元素的相同事件同时绑定多个响应函数,这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
var btn01 = document.getElementById("btn01");
btn01.addEventListener("click",function() {
alert(1);
},false);
var btn02 = document.getElementById("btn02");
btn01.addEventListener("click",function() {
alert(2);
},false);
this 是谁,由调用方式决定
事件的传播
分为3个阶段:
1.捕获阶段:从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
2.目标阶段:事件捕获到目标元素,捕获结束开始在目标元素上触发事件
3.冒泡阶段:事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
如果希望在捕获阶段就触发事件,可以将addEventListener() 的第三个参数设置为true,一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
bind() 方法
bind()
方法创建一个新的函数,在 bind()
被调用时,这个新函数的 this
被指定为 bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
语法:
function.bind(thisArg[, arg1[, arg2[, ...]]])
回调函数
函数也是对象,函数是用 Function() 构造函数创建的Function 对象,Function对象包含一个字符串,字符串包含函数的JS代码
//可以这样创建函数
滚轮事件
onmousewheel 鼠标滚轮滚动的事件,会在滚轮滚动时触发
box1.onmousewheelDelta 可以获取鼠标滚轮滚动的方向
键盘事件
键盘事件一般绑定给 可以获取到焦点的对象,或是document
document.onkeyup
document.onkeydown
document.onkeydown = function(event) {
console.log(event.keyCode;
}
除了keyCode还有altKey,ctrlKey,shiftKey
return false:取消默认行为
在文本框中输入内容,属于onKeydown的默认行为
键盘移动div
上38 下40 左37 右39
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<style type="text/css">
#box1 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div id="box1"></div>
</body>
<script type="text/javascript">
document.onkeydown = function(event) {
switch(event.keyCode) {
case 37:
box1.style.left = box1.offsetLeft - 10 + "px";
break;
case 38:
box1.style.top = box1.offsetTop - 10 + "px";
break;
case 39:
box1.style.left = box1.offsetLeft + 10 + "px";
break;
case 40:
box1.style.top = box1.offsetTop + 10 + "px";
break;
}
}
</script>
</html>