JavaScript08-DOM操作事件01
1.事件对象
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
#div01 {
width: 300px;
height: 100px;
border: 1px solid black;
}
#div02 {
width: 300px;
height: 50px;
margin-top: 10px;
border: 1px solid black;
}
</style>
<script>
window.onload = function () {
// 获取鼠标在div01中移动的坐标,然后再div02中显示。
let div01 = document.getElementById('div01');
let div02 = document.getElementById('div02');
/**
* 当事件的响应函数触发时,浏览器都会传递一个参数作为回调函数的实参。
* 这个实参就是事件对象,事件对象存储了当前事件的相关信息。
* @param event 事件对象
*/
// 当鼠标在div01上移动时,触发onmousemove事件。
div01.onmousemove = function (event) {
let x = event.clientX;
let y = event.clientY;
div02.innerText = `x = ${x}, y = ${y}`;
}
}
</script>
</head>
<body>
<div id="div01"></div>
<div id="div02"></div>
</body>
</html>
2.练习-div随鼠标移动
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
body {
height: 3000px;
}
#div01 {
width: 100px;
height: 100px;
border: 1px solid black;
background-color: red;
/*position: fixed;*/
position: absolute;
}
</style>
<script>
window.onload = function () {
let div01 = document.getElementById('div01');
// 需要给当前的DOM设置鼠标移动事件
document.onmousemove = function (event) {
let x = event.clientX;
let y = event.clientY;
// 需要div开启定位(position: absolute;),设置偏移量才有效。
// div01.style.left = x + 'px';
// div01.style.top = y + 'px';
// 设置div01.style.left = x + 'px',当body有滚动条时,clientX获取的时当前粗窗口的x坐标,
// 会出现div不在当前窗口显示的问题。
// 解决办法 1 设置div的position: fixed;,让div的定位以当期窗口作为参照物。
// 解决办法 2 使用pageX,获取鼠标在当前页(窗口)的x坐标。不过pageX这个属性还在试验中。
// div01.style.left = event.pageX + 'px';
// div01.style.top = event.pageY + 'px';
// 解决办法 3 使用document.documentElement.scrollLeft获取滚动条移动的距离,
// 滚动条移动的距离+鼠标在当前窗口的坐标=鼠标在当前页的坐标。
div01.style.left = x + document.documentElement.scrollLeft + 'px';
div01.style.top = y + document.documentElement.scrollTop + 'px';
}
}
</script>
</head>
<body>
<div id="div01"></div>
</body>
</html>
3.事件的冒泡
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
#div01 {
width: 100px;
height: 100px;
border: 1px solid black;
background-color: #99ff99;
}
#sp01 {
background-color: orange;
}
</style>
<script>
// 冒泡是指事件的向上传导,当元素上的事件被触发时,其祖先元素上的相同事件也会被触发。
// 1 冒泡的发生只和结构有关,和元素的位置无关。
// 2 取消事件冒泡的两种方式。
// 1) event.cancelBubble = true;
// 2) event.stopPropagation();
window.onload = function () {
document.getElementById('sp01').onclick = function (event) {
// 取消事件的冒泡,取消事件的冒泡后,当前事件不会冒泡给div01
//event.cancelBubble = true;
event.stopPropagation();
alert('sp01');
};
document.getElementById('div01').onclick = function () {
// 当前div的点击事件会冒泡给document
alert('div01');
};
document.onclick = function () {
alert('document');
}
}
</script>
</head>
<body>
<div id="div01">
我是div01
<div id="sp01">我是span</div>
</div>
</body>
</html>
4.事件的绑定
<html lang="en">
<head>
<meta charset="UTF-8">
<script>
window.onload = function () {
let btn01 = document.getElementById('btn01');
// 1 给btn01绑定单击事件。
// 通过给onclick属性设置值的方式绑定事件,只能绑定一个事件,
// 如果绑定多个事件,则前面的事件被覆盖,所以在开发中不经常使用。
btn01.onclick = function () {
alert('btn01 A01');
};
btn01.onclick = function () {
alert('btn01 A02');
};
// 2 通过addEventListener()添加事件,如果添加了多个事件,则多个事件都会触发。
// addEventListener() 有三个参数。
// 1 绑定的事件。如click,不需要on。
// 2 事件触发执行的函数。
// 3 是否进行事件的捕获,默认false,所以发生的是事件的冒泡;true,会发生事件的捕获,捕获时不会发生事件的冒泡。
let btn02 = document.getElementById('btn02');
function client01() {
alert('btn02 A01');
}
// 通过addEventListener()添加事件。
btn02.addEventListener('click', client01);
function client02() {
alert('btn02 A02');
}
btn02.addEventListener('click', client02);
// 通过addEventListener() 绑定的事件如果需要删除,则需要使用removeEventListener()函数。
btn02.removeEventListener('click', client02);
}
</script>
</head>
<body>
<button id="btn01">btn01</button>
<button id="btn02">btn02</button>
</body>
</html>
5.事件的捕获
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
#div01 {
width: 300px;
height: 300px;
background-color: #99ff99;
}
#div02 {
width: 200px;
height: 200px;
background-color: red;
}
#div03 {
width: 100px;
height: 100px;
background-color: orange;
}
</style>
<script>
window.onload = function () {
// 关于事件的传播微软和网景有不同的理解。
// 微软:事件应该由内向外传播,即先触发后代元素的事件,然后触发祖先元素的事件,事件的冒泡。
// 网景,事件应该由外向内传播,即先触发祖先元素的事件,然后触发后代元素的时间,事件的捕获。
// W3C将这两种理念进行整合,将事件分为三个阶段。
// 1 事件的捕获。从最外层元素(window)向目标元素进行事件的捕获。
// 2 目标元素。事件捕获到目标元素,捕获停止。
// 3 事件的冒泡。从目标元素开始向最外层元素进行事件的传导。
// 默认情况下,事件是在冒泡阶段开始触发的。事件传播行为只能是事件的捕获和事件的冒泡中的一个。
let div01 = document.getElementById('div01');
let div02 = document.getElementById('div02');
let div03 = document.getElementById('div03');
// addEventListener() 的第三个参数,是否进行事件的捕获,默认false,所以发生的是事件的冒泡。
// true,会发生事件的捕获,不会发生事件的冒泡。
div01.addEventListener('click', function () {
alert('div01');
}, true);
div02.addEventListener('click', function () {
alert('div02');
}, true);
div03.addEventListener('click', function () {
alert('div03');
}, true);
let a01 = document.getElementById('a01');
// 通过addEventListener()添加事件不能通过return false;来取消事件的默认行为。
// addEventListener()事件的事件,可以通过preventDefault()来取消事件的默认行为。
a01.addEventListener('click', function (event) {
alert('123');
// 取消事件的默认行为。
event.preventDefault();
return false;
});
}
</script>
</head>
<body>
<div id="div01">
<div id="div02">
<div id="div03">
</div>
</div>
</div>
<a href="https://www.baidu.com" id="a01">去百度</a>
</body>
</html>
6.练习-div随鼠标移动,解决div移动到其他div下的问题
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
#div01 {
width: 100px;
height: 100px;
border: 1px solid black;
background-color: orange;
position: absolute;
}
#div02 {
width: 100px;
height: 100px;
margin-left: 500px;
margin-top: 100px;
border: 1px solid black;
background-color: black;
position: absolute;
}
</style>
<script>
window.onload = function () {
let div01 = document.getElementById('div01');
// 给div绑定鼠标按下去的事件,鼠标按下去之后修改div的坐标。
div01.onmousedown = function () {
// 计算鼠标相对于div的左偏移量,相当于获取鼠标在div中的坐标。
let x = event.clientX - div01.offsetLeft;
// 计算鼠标相对于div的上偏移量
let y = event.clientY - div01.offsetTop;
// 通过document的鼠标移动事件修改div的坐标。
document.onmousemove = function (event) {
div01.style.left = event.clientX - x + 'px';
div01.style.top = event.clientY - y + 'px';
};
// 给document绑定鼠标松开的事件,松开之后删除document的鼠标移动事件和鼠标松开事件。
// 这里需要将鼠标松开事件绑定为document,不能绑定为div01,因为如果将div01移动到其他div(div01的兄弟)下,
// div01的鼠标松开事件onmouseup是无法触发的,所以需要绑定给document。同时由于事件冒泡的特性,
// 及时就是div01移动到其他div下,鼠标的松开事件也会传导给document。
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
}
};
}
</script>
</head>
<body>
<div id="div01"></div>
<div id="div02"></div>
</body>
</html>
7.事件的委派
<html lang="en">
<head>
<meta charset="UTF-8">
<title>01-事件的委派</title>
<script>
window.onload = function () {
// 1 将点击事件绑定给了a标签,如果新增一个a标签,就需要给新增的a设置点击事件。
// let items = document.getElementsByTagName('a');
// for (let i = 0;i < items.length;i++) {
// items[i].addEventListener('click', function () {
// alert('点击了a');
// })
// }
// 2 添加btn01后,给ul中添加一个同样的ul,这时a标签就需要设置点击事件。
// 解决增加新的ul后需要设置点击事件的办法,将点击事件绑定给ul,这时由于事件的冒泡,点击a之后就会传递给ul。
let ul = document.getElementsByTagName('ul')[0];
document.getElementById('btn01').onclick = function () {
ul.insertAdjacentHTML('beforeend', '<li><a href="javascript:;">新超链接</a></li>');
};
// 3 事件的委派:当需要为多个函数绑定相同的响应事件时,可以将响应事件绑定到他们共同的祖先元素。
// 这样只需要绑定一次就可以让所有的元素都拥有响应事件,即使元素是新添加的也会拥有响应事件。
// 4 给ul绑定点击事件之后存在的问题:我们只希望点击ul中的a标签时触发点击事件,
// 但是给ul绑定点击事件后,点击ul也触发了点击事件。解决办法:通过event.target来
// 获取触发事件的对象,然后进行判断。
ul.addEventListener('click', function (event) {
// event.target 获取触发事件的对象。
// event.target.tagName 获取触发事件对象后,在获取这个对象的标签名,即只有当点击a标签之后才
// 触发点击事件。
if (event.target.tagName.toUpperCase() === 'A') {
alert('点击了a');
}
})
}
</script>
</head>
<body>
<button id="btn01">btn01</button>
<button id="btn02">btn02</button>
<ul>
<li>
<a href="javascript:;">超链接</a>
</li>
<li>
<a href="javascript:;">超链接</a>
</li>
<li>
<a href="javascript:;">超链接</a>
</li>
</ul>
</body>
</html>
8.JavaScript修改标签的class属性
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.b1 {
width: 100px;
height: 100px;
background-color: red;
}
.b2 {
width: 200px;
height: 200px;
background-color: orange;
}
</style>
<script>
window.onload = function () {
document.getElementById('btn01').onclick = function () {
let div01 = document.getElementById('div01');
// 切换class,可以通过classList来修改class属性。
// 1 classList的类型是DOMTokenList。
// 2 classList的常用方法。
// add() 向元素添加一个或者多个类,如果元素中已经要添加的类,则不会重复添加。
// remove() 用来移除元素中的类。
// replace() 使用一个新的类替换原有的类。
// toggle() 切换元素的类。如果元素有这个类,则删除;没有,则添加。
// contains() 元素中是否包含这个类。
let classList = div01.classList;
//classList.add('b2');
//classList.remove('b1');
//classList.replace('b1', 'b2');
classList.toggle('b2');
console.log(classList.contains('b2'));
}
}
</script>
</head>
<body>
<button id="btn01">btn01</button>
<div class="b1" id="div01"></div>
</body>
</html>
9.练习-div随鼠标移动,解决选择文字时,div移动出现的问题
<head>
<meta charset="UTF-8">
<style>
#div01 {
width: 100px;
height: 100px;
border: 1px solid black;
background-color: orange;
position: absolute;
}
#div02 {
width: 100px;
height: 100px;
margin-left: 500px;
margin-top: 100px;
border: 1px solid black;
background-color: black;
position: absolute;
}
</style>
<script>
window.onload = function () {
let div01 = document.getElementById('div01');
div01.onmousedown = function (event) {
// 当我们选中文字并进行拖拽时,浏览器会尝试将文字在搜索引擎中搜索,
// 这是浏览器的默认行为,会影响到拖拽功能。
// 可以通过取消浏览器的默认拖拽文字的行为来解决这个问题。
event.preventDefault();
let x = event.clientX - div01.offsetLeft;
let y = event.clientY - div01.offsetTop;
document.onmousemove = function (event) {
div01.style.left = event.clientX - x + 'px';
div01.style.top = event.clientY - y + 'px';
};
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
}
};
}
</script>
</head>
<body>
hello hello
<div id="div01"></div>
<div id="div02"></div>
</body>
</html>
10.练习-div随鼠标移动代码封装
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
#div01 {
width: 100px;
height: 100px;
background-color: orange;
}
#div02 {
width: 100px;
height: 100px;
background-color: red;
}
#div03 {
width: 100px;
height: 100px;
background-color: black;
}
.drag {
position: absolute;
}
</style>
</head>
<body>
<div id="div01" class="drag"></div>
<div id="div02" class="drag"></div>
<div id="div03" class="drag"></div>
<script>
(function () {
// 封装div随鼠标移动的功能,只要div中包含drag属性,就可以随鼠标进行移动。
let target = null;
let left, top;
document.addEventListener('mousedown', function (event) {
// 元素包含drag属性才触发。
if (event.target.classList.contains('drag')) {
event.preventDefault();
target = event.target;
left = event.clientX - target.offsetLeft;
top = event.clientY - target.offsetTop;
}
});
// 给document绑定鼠标移动事件
document.addEventListener('mousemove', function (event) {
// 发送了鼠标按下事件才触发。
if (target) {
target.style.left = event.clientX - left + 'px';
target.style.top = event.clientY - top + 'px';
}
});
// 给document绑定鼠标松开事件
document.addEventListener('mouseup', function () {
target = null;
})
})();
</script>
</body>
</html>