console.log('1');
console.log('2');
console.log('3');
console.log('1');
setTimeout(() => {
console.log('2');
}, 1000);
console.log('3');
<body>
<script>
console.log(1);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
console.log('responseText', this.responseText);
}
};
xhr.open("GET", "data.txt", false);
xhr.send();
console.log(2);
</script>
</body>
<body>
<button onclick="alert('Hello, World!')">Click me!</button>
</body>
<body>
<button onclick="alert('Hello')">Click me!</button>
<script>
const button = document.querySelector("button");
button.onclick = function () {
console.log(this,"World");
};
</script>
</body>
addEventListener方法时,可以选择传递一个布尔值来表示是否在捕获阶段处理事件。默认情况下,该值为false,表示事件处理函数在冒泡阶段执行event.target表示触发事件的目标元素event.type表示事件的类型(如"click")event.currentTarget表示当前处理事件的元素
<body>
<div id="parent">
<div id="child">
click
</div>
</div>
<script>
const parent = document.querySelector("#parent");
const child = document.querySelector("#child");
function captureClick(event) {
//event.stopPropagation();
console.log('captureClick', 'target=', event.target.id, 'currentTarget=', event.currentTarget.id);
}
function bubbleClick(event) {
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
//event.stopPropagation();
//event.stopImmediatePropagation();
console.log('bubbleClick', 'target=', event.target.id, 'currentTarget=', event.currentTarget.id);
}
function bubbleClick2(event) {
console.log('bubbleClick2')
}
parent.addEventListener("click", captureClick, true);
child.addEventListener("click", captureClick, true);
parent.addEventListener("click", bubbleClick, false);
child.addEventListener("click", bubbleClick, false);
child.addEventListener("click", bubbleClick2, false);
</script>
</body>
addEventListener是一个DOM方法,用于在指定元素上绑定事件处理程序。通过使用addEventListener,你可以为元素的某个事件添加一个或多个处理程序,而不会覆盖已存在的处理程序。这使得事件处理更加灵活,同时也支持了事件捕获和冒泡event的target属性指向触发事件的原始目标元素。换句话说,target是实际上引发事件的元素。在事件生命周期中,target属性在捕获阶段、目标阶段和冒泡阶段保持不变。因此,你可以使用event.target来确定实际发生交互的元素,无论事件处理程序是在哪个阶段执行的event的currentTarget属性指向当前处理事件的元素。换句话说,currentTarget是事件处理程序所附加的元素。与target属性不同,currentTarget属性在事件生命周期的不同阶段可能指向不同的元素,因为事件处理程序可以在不同的元素上执行element.addEventListener(eventType, eventHandler, useCapture);
removeEventListener方法event.stopPropagation()方法用于阻止事件在DOM树中进一步传播。当调用event.stopPropagation()时,事件将不再向上(冒泡阶段)或向下(捕获阶段)传播,但仍会触发当前元素上的其他同类型事件监听器。换句话说,event.stopPropagation()只会阻止事件在当前元素的祖先或子孙元素上的事件监听器被触发event.stopImmediatePropagation()方法不仅阻止事件在DOM树中的传播,还阻止当前元素上的其他同类型事件监听器被触发。当调用event.stopImmediatePropagation()时,当前元素上的其他同类型事件处理程序将不会执行| 事件名 | 介绍 | 是否可冒泡 |
|---|---|---|
| mousedown | 当按下鼠标按钮时触发该事件 | 是 |
| mouseup | 当释放鼠标按钮时触发该事件 | 是 |
| click | 当鼠标单击元素时触发该事件(mousedown 和 mouseup 事件顺序发生在同一元素上 |
是 |
| dblclick | 当鼠标在元素上双击时触发该事件 | 是 |
| mouseover | 当鼠标指针移动到元素上时触发该事件 | 是 |
| mousemove | 当鼠标在元素上移动时触发该事件 | 是 |
| mouseout | 当鼠标指针移出元素时触发该事件 | 是 |
| mouseenter | 当鼠标指针进入元素时触发该事件(不冒泡) | 否 |
| mouseleave | 当鼠标指针离开元素时触发该事件(不冒泡) | 否 |
| contextmenu | 当在元素上单击鼠标右键(或在 Mac 上按 control + 点击)时触发该事件,通常用于显示自定义上下文菜单 | 是 |
mousedown 事件是一个鼠标事件,当用户在浏览器中按下鼠标按钮时触发。这个事件可以在任何可见的 HTML 元素上发生,包括文本、图像、按钮等<body>
<button id="button">按钮</button>
<script>
const button = document.getElementById("button");
button.addEventListener("mousedown", function (event) {
console.log("mousedown");
});
</script>
</body>
<body>
<button id="button">按钮</button>
<script>
const button = document.getElementById("button");
button.addEventListener("mousedown", function (event) {
console.log("mousedown");
});
button.addEventListener("mouseup", function (event) {
console.log("mouseup");
});
</script>
</body>
click 事件是一个在用户点击元素时触发的浏览器事件。当用户在元素上按下并释放鼠标按钮(通常是左键)时,浏览器会触发这个事件click 事件常用于处理元素的点击操作,如按钮点击、链接跳转等<body>
<button id="button">按钮</button>
<script>
const button = document.getElementById("button");
button.addEventListener("mousedown", function (event) {
console.log("mousedown");
});
button.addEventListener("mouseup", function (event) {
console.log("mouseup");
});
button.addEventListener("click", function (event) {
console.log("click");
});
</script>
</body>
<body>
<button id="button">按钮</button>
<script>
const button = document.getElementById("button");
button.addEventListener("mousedown", function (event) {
console.log("mousedown");
});
button.addEventListener("mouseup", function (event) {
console.log("mouseup");
});
button.addEventListener("click", function (event) {
console.log("click");
});
</script>
</body>


<head>
<style>
#container {
width: 100px;
height: 100px;
background-color: lightgreen;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const container = document.getElementById("container");
container.addEventListener("mouseover", function (event) {
console.log("mouseover");
});
</script>
</body>
<head>
<style>
#container {
width: 100px;
height: 100px;
background-color: lightgreen;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const container = document.getElementById("container");
container.addEventListener("mouseover", function (event) {
console.log("mouseover");
});
container.addEventListener("mousemove", function (event) {
console.log("mousemove");
});
</script>
</body>
<head>
<style>
#container {
width: 100px;
height: 100px;
background-color: lightgreen;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const container = document.getElementById("container");
container.addEventListener("mouseover", function (event) {
console.log("mouseover");
});
container.addEventListener("mousemove", function (event) {
console.log("mousemove");
});
container.addEventListener("mouseout", function (event) {
console.log("mouseout");
});
</script>
</body>


<head>
<style>
#container {
width: 100px;
height: 100px;
background-color: lightgreen;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const container = document.getElementById("container");
container.addEventListener("mouseover", function (event) {
console.log("mouseover");
});
container.addEventListener("mousemove", function (event) {
console.log("mousemove");
});
container.addEventListener("mouseout", function (event) {
console.log("mouseout");
});
container.addEventListener("mouseenter", function (event) {
console.log("mouseenter");
});
</script>
</body>
<head>
<style>
#container {
width: 100px;
height: 100px;
background-color: lightgreen;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const container = document.getElementById("container");
container.addEventListener("mouseover", function (event) {
console.log("mouseover");
});
container.addEventListener("mousemove", function (event) {
console.log("mousemove");
});
container.addEventListener("mouseout", function (event) {
console.log("mouseout");
});
container.addEventListener("mouseenter", function (event) {
console.log("mouseenter");
});
container.addEventListener("mouseleave", function (event) {
console.log("mouseleave");
});
</script>
</body>
mouseover
mouseenter
mousemove
mouseout
mouseleave
head>
<style>
#parent {
width: 200px;
height: 200px;
background-color: lightgreen;
}
#child {
width: 100px;
height: 100px;
background-color: lightpink;
}
</style>
</head>
<body>
<div id="parent">
<div id="child"></div>
</div>
<script>
const parent = document.getElementById("parent");
parent.addEventListener("mouseover", function (event) {
console.log("parent mouseover");
});
parent.addEventListener("mousemove", function (event) {
//console.log("parent mousemove");
});
parent.addEventListener("mouseout", function (event) {
console.log("parent mouseout");
});
parent.addEventListener("mouseenter", function (event) {
console.log("parent mouseenter");
});
parent.addEventListener("mouseleave", function (event) {
console.log("parent mouseleave");
});
const child = document.getElementById("child");
child.addEventListener("mouseover", function (event) {
console.log("child mouseover");
});
child.addEventListener("mousemove", function (event) {
//console.log("child mousemove");
});
child.addEventListener("mouseout", function (event) {
console.log("child mouseout");
});
child.addEventListener("mouseenter", function (event) {
console.log("child mouseenter");
});
child.addEventListener("mouseleave", function (event) {
console.log("child mouseleave");
});
</script>
</body>
parent mouseover
parent mouseenter
parent mouseout
child mouseover
parent mouseover
child mouseenter
child mouseout
parent mouseout
child mouseleave
parent mouseover
parent mouseout
parent mouseleave
<body>
<div id="customElement">右键点击</div>
<script>
const customElement = document.getElementById("customElement");
customElement.addEventListener("contextmenu", function (event) {
console.log('contextmenu');
});
</script>
</body>
// 绑定到 window 对象
window.addEventListener('keydown', function(event) {
// 处理键盘事件
});
// 绑定到 document 对象
document.addEventListener('keydown', function(event) {
// 处理键盘事件
});
// 绑定到具体的 HTML 元素
const inputElement = document.getElementById('my-input');
inputElement.addEventListener('keydown', function(event) {
// 处理键盘事件
});
keydown:当用户按下一个键时触发keydown 事件在用户按下键盘上的任意键时触发,包括字符键(字母、数字、标点符号等)和非字符键(如功能键、方向键等)。当你需要捕获用户与键盘的所有交互时,可以使用 keydown 事件document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.key === 's') {
event.preventDefault(); // 阻止浏览器默认行为
console.log('执行自定义保存操作');
}
});
keypress:当用户按下并松开一个字符键(如字母、数字或标点符号键)时触发。注意,非字符键(例如功能键、方向键)不会触发此事件<body>
<input type="text" id="phone" placeholder="请输入电话号码" />
<script>
const phoneInput = document.getElementById('phone');
phoneInput.addEventListener('keypress', function (event) {
const key = event.key;
// 如果按下的不是数字,则阻止输入
if (!isFinite(key)) {
event.preventDefault();
return;
}
// 获取当前输入框中的值
const currentValue = phoneInput.value;
// 根据电话号码格式,添加分隔符
if (currentValue.length === 3) {
phoneInput.value += '-';
}
});
</script>
</body>
keyup:当用户松开一个键时触发let startTime;
document.addEventListener('keydown', function(event) {
if (event.key === 'a') {
startTime = new Date().getTime();
}
});
document.addEventListener('keyup', function(event) {
if (event.key === 'a') {
let endTime = new Date().getTime();
let duration = endTime - startTime;
console.log('按键持续时间:', duration, '毫秒');
}
});
const inputBox = document.querySelector('#inputBox');
inputBox.addEventListener('keyup', function(event) {
let searchText = inputBox.value;
console.log('执行实时搜索,关键词:', searchText);
});
| 事件名 | 介绍 | 是否可冒泡 |
|---|---|---|
| input | 当元素的值发生变化时触发该事件 | 是 |
| change | 当元素的值发生变化时触发该事件 | 是 |
| focus | 当元素获得焦点时触发该事件 | 否 |
| blur | 当元素失去焦点时触发该事件 | 否 |
| submit | 当提交表单时触发该事件 | 是 |
| reset | 当重置表单时触发该事件 | 是 |
| select | 当用户选中输入框中的文本时触发该事件 | 是 |
<body>
<input />
<script>
var input = document.querySelector('input');
input.addEventListener('input', function (event) {
console.log('input');
});
</script>
</body>
<body>
<input />
<script>
var input = document.querySelector('input');
input.addEventListener('input', function (event) {
console.log('input');
});
input.addEventListener('change', function (event) {
console.log('change');
});
</script>
</body>
<body>
<input />
<script>
var input = document.querySelector('input');
input.addEventListener('input', function (event) {
console.log('input');
});
input.addEventListener('change', function (event) {
console.log('change');
});
input.addEventListener('focus', function (event) {
console.log('focus');
});
</script>
</body>
<body>
<input />
<script>
var input = document.querySelector('input');
input.addEventListener('input', function (event) {
console.log('input');
});
input.addEventListener('change', function (event) {
console.log('change');
});
input.addEventListener('focus', function (event) {
console.log('focus');
});
input.addEventListener('blur', function (event) {
console.log('blur');
});
</script>
</body>
<body>
<form>
<label for="name">Name:</label><br>
<input type="text" id="name" name="name"><br>
<input type="submit" value="Submit">
</form>
<script>
// 获取表单元素
const form = document.querySelector('form');
// 添加 submit 事件监听器
form.addEventListener('submit', function(event) {
// 阻止表单的默认提交行为
event.preventDefault();
// 这里可以添加你自己的表单处理代码
console.log('Form submitted!');
});
</script>
</body>
| 事件名 | 介绍 | 是否可冒泡 |
|---|---|---|
| scroll | 当元素或窗口滚动时触发 | 是 |
| load | 当页面加载完成时触发 | 否 |
| resize | 当窗口或框架被重新调整大小时触发 | 否 |
| DOMContentLoaded | 当HTML文档被完全加载和解析时触发 | 是 |
| unload | 当页面完全卸载时触发 | 否 |
| beforeunload | 当窗口或标签页关闭前触发 | 否 |
| abort | 当加载资源过程被用户终止时触发 | 是 |
| error | 当加载资源发生错误时触发 | 是 |
| online | 当设备重新连接到互联网时触发 | 是 |
| offline | 当设备失去互联网连接时触发 | 是 |
<body>
<div id="scrollable-element" style="height:500px;overflow: auto;">
<div style="height: 1000px; background-color: lightgreen;"></div>
</div>
<script>
window.addEventListener('scroll', function (event) {
console.log('页面滚动了');
});
const scrollableElement = document.querySelector('#scrollable-element');
scrollableElement.addEventListener('scroll', function (event) {
console.log('元素滚动了');
});
</script>
</body>
<body>
<script>
window.addEventListener('resize', function (event) {
console.log('窗口大小发生了变化');
});
</script>
</body>
<body>
<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" />
<script>
window.addEventListener('load', function (event) {
console.log('页面加载完成');
});
const imageElement = document.querySelector('img');
imageElement?.addEventListener('load', function (event) {
console.log('图片加载完成');
});
const scriptElement = document.createElement('script');
scriptElement.src = 'script.js';
scriptElement.addEventListener('load', function (event) {
console.log('脚本加载完成');
});
document.head.appendChild(scriptElement);
</script>
</body>
<body>
<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" />
<script>
window.addEventListener('load', function (event) {
console.log('页面加载完成');
});
const imageElement = document.querySelector('img');
imageElement?.addEventListener('load', function (event) {
console.log('图片加载完成');
});
const scriptElement = document.createElement('script');
scriptElement.src = 'script.js';
scriptElement.addEventListener('load', function (event) {
console.log('脚本加载完成');
});
document.head.appendChild(scriptElement);
document.addEventListener('DOMContentLoaded', function (event) {
console.log('HTML 文档已加载和解析');
});
</script>
</body>
| 事件名 | 介绍 | 是否可冒泡 |
|---|---|---|
| touchstart | 触摸屏幕时触发的事件 | 是 |
| touchmove | 触摸点在屏幕上移动时触发的事件 | 是 |
| touchend | 触摸点离开屏幕时触发的事件 | 是 |
| touchcancel | 触摸事件被取消时触发的事件(如来电) | 是 |
| gesturestart | 当两个触摸点开始接触屏幕时触发的事件 | 否 |
| gesturechange | 当两个触摸点在屏幕上移动时触发的事件 | 否 |
| gestureend | 当两个触摸点离开屏幕时触发的事件 | 否 |
<body>
<div id="container" style="width:200px;height:200px;background-color: lightgreen;"></div>
<script>
const container = document.getElementById('container');
container.addEventListener("touchstart", function (event) {
console.log('touchstart');
});
</script>
</body>
<body>
<div id="container" style="width:200px;height:200px;background-color: lightgreen;"></div>
<script>
const container = document.getElementById('container');
container.addEventListener("touchstart", function (event) {
console.log('touchstart');
});
container.addEventListener("touchmove", function (event) {
console.log('touchmove');
});
</script>
</body>
<body>
<div id="container" style="width:200px;height:200px;background-color: lightgreen;"></div>
<script>
const container = document.getElementById('container');
container.addEventListener("touchstart", function (event) {
console.log('touchstart');
});
container.addEventListener("touchmove", function (event) {
console.log('touchmove');
});
container.addEventListener("touchend", function (event) {
console.log('touchend');
});
</script>
</body>
<body>
<div id="customElement">右键点击我查看自定义菜单</div>
<ul id="contextMenu" style="display:none; position:absolute;">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
</ul>
<script>
const customElement = document.getElementById("customElement");
const contextMenu = document.getElementById("contextMenu");
customElement.addEventListener("contextmenu", function (event) {
event.preventDefault();
contextMenu.style.display = "block";
contextMenu.style.left = event.pageX + "px";
contextMenu.style.top = event.pageY + "px";
});
document.addEventListener("click", function () {
contextMenu.style.display = "none";
});
</script>
</body>
<body>
<a id="nav" href="http://www.baidu.com">百度</a>
<script>
const nav = document.getElementById('nav');
nav.addEventListener("click", function (event) {
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
alert('click');
});
</script>
</body>
offsetX 和 offsetY 属性表示事件触发点相对于事件目标元素的位置。换句话说,它们表示鼠标指针在目标元素内的坐标。这些坐标是相对于目标元素左上角的水平和垂直距离clientX 和 clientY 属性表示事件触发点相对于浏览器视口的位置。视口是浏览器窗口内用于显示网页内容的区域。这些坐标是相对于视口左上角的水平和垂直距离,不包括滚动条pageX 和 pageY 属性表示事件触发点相对于整个文档的位置。这些坐标是相对于文档左上角的水平和垂直距离,包括滚动条。换句话说,它们是基于文档的绝对坐标screenX 和 screenY 属性表示事件触发点相对于屏幕的位置。这些坐标是相对于屏幕左上角的水平和垂直距离。需要注意的是,这些坐标与网页内容无关,而是基于物理屏幕的位置
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Event Coordinates</title>
<style>
* {
padding: 0;
margin: 0;
}
body {
height: 2000px;
}
#container {
width: 200px;
height: 200px;
background-color: lightblue;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 300px;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
//定义一个函数,用于将数字四舍五入到最接近的特定位数(默认为100)
function roundToPlace(num, roundingPlace = 100) {
return Math.round(num / roundingPlace) * roundingPlace;
}
//找到HTML中ID为'container'的元素
const container = document.getElementById('container');
//为该元素添加一个点击事件监听器
container.addEventListener('click', (event) => {
//在点击事件触发时,输出点击点的x坐标相对于触发事件元素的偏移量,并四舍五入到最近的100
console.log('offsetX:', roundToPlace(event.offsetX));
//输出点击点的x坐标相对于浏览器可视区的位置,并四舍五入到最近的100
console.log('clientX:', roundToPlace(event.clientX));
//输出点击点的x坐标相对于完整页面的位置,并四舍五入到最近的100
console.log('pageX:', roundToPlace(event.pageX));
//输出点击点的x坐标相对于用户电脑屏幕的位置,并四舍五入到最近的10
console.log('screenX:', roundToPlace(event.screenX, 10));
//以下四行与上面类似,但是输出的是y坐标而非x坐标
console.log('offsetY:', roundToPlace(event.offsetY));
console.log('clientY:', roundToPlace(event.clientY));
console.log('pageY:', roundToPlace(event.pageY));
console.log('screenY:', roundToPlace(event.screenY, 10));
});
//设置一个定时器,在1秒后将页面滚动到距离顶部100像素的位置
setTimeout(() => {
document.documentElement.scrollTop = 100;
}, 1000);
</script>
</body>
key属性表示按下的按键的描述性字符串。例如,当按下 "A" 键时,key 的值为 "a"。同样,当按下方向键时,key 的值为 "ArrowUp"、"ArrowDown"、"ArrowLeft" 或 "ArrowRight"<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Moving Square</title>
<style>
* {
padding: 0;
margin: 0;
}
#box {
position: absolute;
width: 100px;
height: 100px;
background-color: lightblue;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
//获取ID为'box'的元素
const box = document.getElementById('box');
//获取该元素距离页面顶部的距离
let offsetTop = box.offsetTop;
//获取该元素距离页面左边的距离
let offsetLeft = box.offsetLeft;
//定义移动步长为10px
const step = 10;
//定义一个函数,用于根据键盘的方向键移动box元素
function moveBox(event) {
switch (event.key) {
//如果按下的是向上的方向键,则box元素向上移动
case 'ArrowUp':
offsetTop -= step;
break;
//如果按下的是向下的方向键,则box元素向下移动
case 'ArrowDown':
offsetTop += step;
break;
//如果按下的是向左的方向键,则box元素向左移动
case 'ArrowLeft':
offsetLeft -= step;
break;
//如果按下的是向右的方向键,则box元素向右移动
case 'ArrowRight':
offsetLeft += step;
break;
}
//更新box元素的top样式,使其移动到新的位置
box.style.top = `${offsetTop}px`;
//更新box元素的left样式,使其移动到新的位置
box.style.left = `${offsetLeft}px`;
}
//为整个文档添加一个键盘按下的事件监听器,当按下键盘时,调用moveBox函数
document.addEventListener('keydown', moveBox);
</script>
</body>
</html>
<body>
<ul id="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script>
//获取ID为'list'的元素
const list = document.getElementById("list");
//为该元素添加一个点击事件监听器
list.addEventListener("click", function (event) {
//检查点击的目标元素是否为列表项('LI')
if (event.target.tagName === "LI") {
//如果是,弹出一个警告框,显示点击的列表项的内容
alert("You clicked on: " + event.target.textContent);
}
});
</script>
</body>
offsetX 和 offsetY 属性表示事件触发点相对于事件目标元素的位置。换句话说,它们表示鼠标指针在目标元素内的坐标。这些坐标是相对于目标元素左上角的水平和垂直距离clientX 和 clientY 属性表示事件触发点相对于浏览器视口的位置。视口是浏览器窗口内用于显示网页内容的区域。这些坐标是相对于视口左上角的水平和垂直距离,不包括滚动条<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Drag and Drop Example</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<style>
.draggable {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
cursor: move;
}
</style>
</head>
<body>
<div class="draggable" id="draggable"></div>
<script>
//获取ID为'draggable'的元素
const draggable = document.getElementById("draggable");
//定义两个变量用于保存鼠标与拖动元素的偏移量
let offsetX = 0;
let offsetY = 0;
//定义一个标志位,表示当前是否正在拖动
let dragging = false;
//为拖动元素添加一个鼠标按下的事件监听器
draggable.addEventListener("mousedown", (event) => {
//当鼠标按下时,开始拖动
dragging = true;
//计算鼠标点击点与拖动元素左边界和上边界的偏移量
offsetX = event.clientX - draggable.offsetLeft;
offsetY = event.clientY - draggable.offsetTop;
//以下两行代码是另一种获取偏移量的方法,但这里被注释掉了
//offsetX = event.offsetX;
//offsetY = event.offsetY;
});
//为整个文档添加一个鼠标移动的事件监听器
document.addEventListener("mousemove", function (event) {
//如果正在拖动,更新拖动元素的位置
if (dragging) {
draggable.style.left = event.clientX - offsetX + "px";
draggable.style.top = event.clientY - offsetY + "px";
}
});
//为整个文档添加一个鼠标抬起的事件监听器
document.addEventListener("mouseup", function () {
//当鼠标抬起时,停止拖动
dragging = false;
});
</script>
</body>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Drag and Drop Example</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<style>
.draggable {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
cursor: move;
}
</style>
</head>
<body>
<div class="draggable" id="draggable"></div>
<script>
//获取ID为'draggable'的元素
const draggable = document.getElementById("draggable");
//定义两个变量用于保存鼠标与拖动元素的偏移量
let offsetX = 0;
let offsetY = 0;
//定义一个标志位,表示当前是否正在拖动
let dragging = false;
//为拖动元素添加一个鼠标按下的事件监听器
draggable.addEventListener("mousedown", (event) => {
//当鼠标按下时,开始拖动
dragging = true;
//计算鼠标点击点与拖动元素左边界和上边界的偏移量
offsetX = event.clientX - draggable.offsetLeft;
offsetY = event.clientY - draggable.offsetTop;
//以下两行代码是另一种获取偏移量的方法,但这里被注释掉了
//offsetX = event.offsetX;
//offsetY = event.offsetY;
});
//为整个文档添加一个鼠标移动的事件监听器
document.addEventListener("mousemove", function (event) {
//如果正在拖动,更新拖动元素的位置
if (dragging) {
//计算新的位置
const newX = event.clientX - offsetX;
const newY = event.clientY - offsetY;
//计算窗口的右边界和底边界
const maxLeft = document.documentElement.clientWidth - draggable.offsetWidth;
const maxTop = document.documentElement.clientHeight - draggable.offsetHeight;
//确保新的位置不超过窗口的边界
const clampedX = Math.max(0, Math.min(newX, maxLeft));
const clampedY = Math.max(0, Math.min(newY, maxTop));
//更新元素的位置
draggable.style.left = clampedX + "px";
draggable.style.top = clampedY + "px";
}
});
//为整个文档添加一个鼠标抬起的事件监听器
document.addEventListener("mouseup", function () {
//当鼠标抬起时,停止拖动
dragging = false;
});
</script>
</body>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.box {
position: absolute;
width: 100px;
height: 100px;
background-color: lightblue;
cursor: move;
}
</style>
</head>
<body>
<div class="box" style="left: 50px; top: 50px;"></div>
<div class="box" style="left: 50px; top: 200px;"></div>
<div class="box" style="left: 50px; top: 350px;"></div>
<script>
//定义一个变量用于保存当前正在拖动的元素
let currentDragging = null;
//获取所有class为'box'的元素
const boxes = document.querySelectorAll('.box');
//为每个元素添加一个鼠标按下的事件监听器
boxes.forEach(box => {
box.addEventListener('mousedown', (e) => {
//当鼠标按下时,设置当前正在拖动的元素为该元素,并计算鼠标相对于元素的偏移量
currentDragging = box;
currentDragging.dataset.offsetX = e.offsetX;
currentDragging.dataset.offsetY = e.offsetY;
});
});
//为整个文档添加一个鼠标移动的事件监听器
document.addEventListener('mousemove', (e) => {
//如果当前没有正在拖动的元素,则直接返回
if (!currentDragging) return;
//如果有正在拖动的元素,则更新元素的位置
currentDragging.style.left = (e.clientX - currentDragging.dataset.offsetX) + 'px';
currentDragging.style.top = (e.clientY - currentDragging.dataset.offsetY) + 'px';
});
//为整个文档添加一个鼠标抬起的事件监听器
document.addEventListener('mouseup', () => {
//当鼠标抬起时,清空当前正在拖动的元素
currentDragging = null;
});
</script>
</body>
</html>
proposedX < boxRect.right:这个条件检查当前拖动元素的左边是否在另一个元素的右边之左。如果是,那么这两个元素可能在水平方向上重叠proposedX + currentDragging.offsetWidth > boxRect.left:这个条件检查当前拖动元素的右边是否在另一个元素的左边之右。如果是,那么这两个元素可能在水平方向上重叠。proposedY < boxRect.bottom:这个条件检查当前拖动元素的顶边是否在另一个元素的底边之上。如果是,那么这两个元素可能在垂直方向上重叠proposedY + currentDragging.offsetHeight > boxRect.top:这个条件检查当前拖动元素的底边是否在另一个元素的顶边之下。如果是,那么这两个元素可能在垂直方向上重叠。如果上述所有条件都为真,那么这两个元素在水平和垂直方向上都有重叠,因此我们可以判断它们发生了碰撞。如果任何一个条件为假,那么这两个元素就没有碰撞
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.box {
position: absolute;
width: 100px;
height: 100px;
cursor: move;
}
</style>
</head>
<body>
<div class="box" style="left: 50px; top: 50px;background-color: lightcoral;"></div>
<div class="box" style="left: 50px; top: 200px;background-color: lightblue;"></div>
<div class="box" style="left: 50px; top: 350px;background-color: lightseagreen;"></div>
<script>
// 声明一个变量,用于保存当前正在拖动的元素
let currentDragging = null;
// 获取页面上所有 class 为 'box' 的元素
const boxes = document.querySelectorAll('.box');
// 为每个 box 元素添加鼠标按下事件监听器
boxes.forEach(box => {
box.addEventListener('mousedown', (e) => {
// 当鼠标按下时,将当前元素设置为正在拖动的元素
// 并且计算鼠标相对于元素的 x 和 y 坐标的偏移
currentDragging = box;
currentDragging.dataset.offsetX = e.offsetX;
currentDragging.dataset.offsetY = e.offsetY;
});
});
// 为整个文档添加鼠标移动事件监听器
document.addEventListener('mousemove', (e) => {
// 如果当前没有元素正在被拖动,直接返回
if (!currentDragging) return;
// 计算预期的新位置
const proposedX = e.clientX - currentDragging.dataset.offsetX;
const proposedY = e.clientY - currentDragging.dataset.offsetY;
// 遍历所有的 box 元素
for (const box of boxes) {
// 如果是当前正在拖动的元素,跳过
if (box === currentDragging) continue;
// 获取元素的位置和尺寸
const boxRect = box.getBoundingClientRect();
// 如果预期的新位置和其他元素发生了碰撞,直接返回
if (
proposedX < boxRect.right &&
proposedX + currentDragging.offsetWidth > boxRect.left &&
proposedY < boxRect.bottom &&
proposedY + currentDragging.offsetHeight > boxRect.top
) {
return;
}
}
// 如果没有碰撞,更新元素的位置
currentDragging.style.left = proposedX + 'px';
currentDragging.style.top = proposedY + 'px';
});
// 为整个文档添加鼠标抬起事件监听器
document.addEventListener('mouseup', () => {
// 当鼠标抬起时,清除当前正在拖动的元素
currentDragging = null;
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<style>
body {
display: flex;
padding: 100px;
}
.container {
position: relative;
width: 300px;
height: 300px;
display: inline-block;
}
.container img {
width: 100%;
height: 100%;
}
.magnifier {
width: 100px;
background: rgba(0, 0, 0, 0.2);
position: absolute;
left: 0;
top: 0;
}
.preview {
width: 300px;
position: relative;
display: inline-block;
overflow: hidden;
}
.preview img {
position: absolute;
left: 0;
top: 0;
}
</style>
<title>magnifier</title>
</head>
<body>
<!-- HTML结构部分 -->
<div class="container">
<img src="images/small.jpg" />
<div class="magnifier"></div>
</div>
<div class="preview">
<img src="images/big.jpg" />
</div>
<script>
// 获取相关的DOM元素
const container = document.querySelector('.container');
const magnifier = document.querySelector('.magnifier');
const preview = document.querySelector('.preview');
const largeImg = document.querySelector('.preview img');
// 计算容器的宽高比 clientHeight=2,clientWidth=1,containerRatio=2
const containerRatio = container.clientHeight / container.clientWidth;
// 设置放大镜的高度,以保持宽高比一致
magnifier.style.height = magnifier.clientWidth * containerRatio + 'px';
// 设置预览框的宽高
preview.style.height = preview.clientWidth * containerRatio + 'px';
// 计算预览框放大的比例
const scale = preview.clientWidth / magnifier.clientWidth;
// 设置放大图像的宽度和高度
largeImg.style.width = container.clientWidth * scale + 'px';
largeImg.style.height = container.clientHeight * scale + 'px';
// 监听容器的鼠标移动事件
container.addEventListener('mousemove', (e) => {
const rect = container.getBoundingClientRect();
let x = e.clientX - rect.left - magnifier.clientWidth / 2;
let y = e.clientY - rect.top - magnifier.clientHeight / 2;
// 限制放大镜的位置在容器范围内
x = Math.max(0, Math.min(x, container.clientWidth - magnifier.clientWidth));
y = Math.max(0, Math.min(y, container.clientHeight - magnifier.clientHeight));
// 设置放大镜的位置和显示
magnifier.style.left = x + 'px';
magnifier.style.top = y + 'px';
magnifier.style.display = 'block';
// 设置放大图像的位置和显示
largeImg.style.left = -x * scale + 'px';
largeImg.style.top = -y * scale + 'px';
largeImg.style.display = 'block';
});
// 监听容器的鼠标离开事件
container.addEventListener('mouseleave', () => {
// 隐藏放大镜和放大图像
magnifier.style.display = 'none';
largeImg.style.display = 'none';
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>树形菜单</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<style>
.tree-menu {
display: none;
}
.tree-menu.top-level {
display: block;
}
.tree-menu li {
position: relative;
font-size: 16px;
padding-left: 16px;
line-height: 32px;
}
.tree-menu .toggle-icon {
position: absolute;
left: 0;
top: 10px;
width: 12px;
height: 12px;
font-size: 12px;
line-height: 12px;
text-align: center;
border: 1px solid #AAA;
cursor: pointer;
}
</style>
</head>
<body>
<ul class="tree-menu top-level" id="treeMenu"></ul>
<script>
//获取ID为'treeMenu'的元素
const treeMenu = document.getElementById("treeMenu");
//为该元素添加一个点击事件监听器
treeMenu.onclick = function (e) {
//获取点击的目标元素和它的下一个兄弟元素
let target = e.target;
let submenu = target.nextElementSibling;
//如果点击的目标元素有'toggle-icon'类,并且存在下一个兄弟元素,则切换目标元素的'open'类,并切换下一个兄弟元素的显示状 态
if (target.classList.contains("toggle-icon") && submenu) {
target.classList.toggle("open");
submenu.style.display = submenu.style.display === "block" ? "none" : "block";
}
};
//定义一个函数,根据数据渲染树形菜单的HTML
function renderTree(data) {
let html = "";
data.forEach(item => {
let { name, children, open } = item;
html += `
<li>
<span>${name}</span>
${children ? `<em class="toggle-icon${open ? ' open' : ''}">${open ? '-' : '+'}</em>` : ``}
${children ?
`<ul class="tree-menu" style="display: ${open ? 'block' : 'none'};">
${renderTree(children)}
</ul>`: ``
}
</li>`;
});
return html;
}
let xhr = new XMLHttpRequest();
xhr.open("get", "https://static.zhufengpeixun.com/data_1684067863819.json");
xhr.onreadystatechange = function () {
//当请求成功完成时,解析响应数据并调用resolve函数
if (xhr.readyState === 4 && xhr.status === 200) {
let data = JSON.parse(xhr.response);
let treeHTML = renderTree(data);
treeMenu.innerHTML = treeHTML;
}
};
xhr.send();
</script>
</body>
</html>

window.innerWidth 和 window.innerHeight 是 JavaScript 中的两个属性,它们分别表示浏览器窗口的视口(viewport)宽度和高度。视口是用户在浏览器窗口中能够看到的网页区域window.innerWidth:这个属性表示浏览器视口的宽度(以像素为单位),包括滚动条(如果有的话)。当用户调整浏览器窗口大小时,这个值会发生变化。这个属性在确定网页布局或响应式设计中的断点时非常有用window.innerHeight:这个属性表示浏览器视口的高度(以像素为单位),同样包括滚动条(如果有的话)。当用户调整浏览器窗口大小时,这个值也会发生变化。这个属性在计算网页元素的位置和大小时非常有用,特别是对于那些需要根据窗口高度进行调整的元素window.outerWidth 属性表示浏览器窗口的总宽度,包括窗口边框、工具栏、菜单栏、书签栏和其他浏览器相关部分。这个属性是只读的window.outerHeight 属性表示浏览器窗口的总高度,包括窗口边框、工具栏、菜单栏、书签栏和其他浏览器相关部分。这个属性也是只读的document.documentElement.clientWidth 属性表示文档根元素的可见宽度,包括内边距(padding),但不包括边框(border)、外边距(margin)和滚动条。这个属性以像素为单位。它常用于获取页面内容的可见宽度document.documentElement.clientHeight 属性表示文档根元素的可见高度,包括内边距(padding),但不包括边框(border)、外边距(margin)和滚动条。这个属性以像素为单位。它常用于获取页面内容的可见高度window.innerWidth 会大于或等于 document.documentElement.clientWidth
<body>
<button onclick="displayViewportSize()">Show Viewport Size</button>
<script>
function displayViewportSize() {
const innerWidth = window.innerWidth;
const innerHeight = window.innerHeight;
let outerWidth = window.outerWidth;
let outerHeight = window.outerHeight;
console.log('innerWidth',innerWidth);
console.log('innerHeight',innerHeight);
console.log('outerWidth',outerWidth);
console.log('outerHeight',outerHeight);
}
</script>
</body>


offsetX 和 offsetY 属性表示事件触发点相对于事件目标元素的位置。换句话说,它们表示鼠标指针在目标元素内的坐标。这些坐标是相对于目标元素左上角的水平和垂直距离clientX 和 clientY 属性表示事件触发点相对于浏览器视口的位置。视口是浏览器窗口内用于显示网页内容的区域。这些坐标是相对于视口左上角的水平和垂直距离,不包括滚动条pageX 和 pageY 属性表示事件触发点相对于整个文档的位置。这些坐标是相对于文档左上角的水平和垂直距离,包括滚动条。换句话说,它们是基于文档的绝对坐标screenX 和 screenY 属性表示事件触发点相对于屏幕的位置。这些坐标是相对于屏幕左上角的水平和垂直距离。需要注意的是,这些坐标与网页内容无关,而是基于物理屏幕的位置

getComputedStyle 方法是一个用于获取计算后的样式值的 JavaScript 方法。它接受一个元素节点作为参数,并返回一个 CSSStyleDeclaration 对象,该对象包含了该元素应用的所有计算后的样式属性和对应的值getComputedStyle 方法可以获取元素的各种样式属性,包括尺寸、颜色、字体等等。这些样式属性可以是直接在元素上定义的样式,也可以是通过 CSS 继承、层叠等机制计算得出的样式const element = document.getElementById('myElement');
const styles = getComputedStyle(element);
// 获取元素的背景颜色
const backgroundColor = styles.backgroundColor;
// 获取元素的字体大小
const fontSize = styles.fontSize;
// 获取元素的宽度和高度
const width = styles.width;
const height = styles.height;

| 属性 | 作用 | 关注的节点类型 |
|---|---|---|
| nextElementSibling | 获取当前元素紧邻的下一个兄弟元素 元素节点 | |
| previousElementSibling | 获取当前元素紧邻的上一个兄弟元素 元素节点 | |
| firstElementChild | 获取当前元素的第一个子元素 元素节点 | |
| lastElementChild | 获取当前元素的最后一个子元素 元素节点 | |
| nextSibling | 获取当前节点紧邻的下一个兄弟节点,包括文本节点和注释节点 所有节点类型 | |
| previousSibling | 获取当前节点紧邻的上一个兄弟节点,包括文本节点和注释节点 所有节点类型 | |
| firstChild | 获取当前节点的第一个子节点,包括文本节点和注释节点 所有节点类型 | |
| lastChild | 获取当前节点的最后一个子节点,包括文本节点和注释节点 所有节点类型 |