mouseover/mouseout 有冒泡,忽略层级之间的关系
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>冒泡机制title>
<style>
* {
margin: 0;
padding: 0;
}
#parent {
height: 500px;
width: 500px;
background-color: red;
}
#son {
height: 300px;
width: 300px;
background-color: blue;
}
style>
head>
<body>
<div id="parent">
<div id="son">div>
div>
body>
html>
<script>
let parent = document.getElementById("parent");
let son = document.getElementById("son");
parent.onmouseover =function(){
console.log('parent移入-onmouseover')
}
parent.onmouseout =function(){
console.log('parent移出-onmouseout')
}
son.onmouseover =function(){
console.log('son移入-onmouseover')
}
son.onmouseout =function(){
console.log('son移出-onmouseout')
}
script>
mouseenter/mouseleave 没冒泡,不会忽略层级之间的关系
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>冒泡机制title>
<style>
* {
margin: 0;
padding: 0;
}
#parent {
height: 500px;
width: 500px;
background-color: red;
}
#son {
height: 300px;
width: 300px;
background-color: blue;
}
style>
head>
<body>
<div id="parent">
<div id="son">div>
div>
body>
html>
<script>
let parent = document.getElementById("parent");
let son = document.getElementById("son");
parent.onmouseenter =function(){
console.log('parent移入-onmouseenter')
}
parent.onmouseleave =function(){
console.log('parent移出-onmouseleave')
}
son.onmouseenter =function(){
console.log('son移入-onmouseenter')
}
son.onmouseleave =function(){
console.log('son移出-onmouseleave')
}
script>
减少事件数量,提高性能
预测未来元素,新添加的元素仍然可以触发该事件
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>2.事件委托title>
head>
<body>
<ul class="ulBox">
<li>001li>
<li>002li>
<li>003li>
<p>pppp>
<li>004li>
<li>005li>
ul>
body>
html>
<script>
// let ulBox = document.querySelector(".ulBox");
// let newli1 = document.createElement("li");
// newli1.innerHTML = "aaa";
// ulBox.appendChild(newli1);
// let lis = document.querySelectorAll("li");
// for (let i = 0; i < lis.length; i++) {
// lis[i].onclick = function () {
// console.log(i);
// };
// }
// let newli2 = document.createElement("li");
// newli2.innerHTML = "bbb";
// ulBox.appendChild(newli2);//这个默认没事件
let ulBox = document.querySelector(".ulBox");
let newli1 = document.createElement("li");
newli1.innerHTML = "aaa";
ulBox.appendChild(newli1);
ulBox.onclick = function (e) {
if (e.target.tagName === "LI") {
console.log(e.target);
}
};
let newli2 = document.createElement("li");
newli2.innerHTML = "bbb";
ulBox.appendChild(newli2); //这个依旧有事件
script>
避免内存外泄,在低版本的IE中,防止删除元素而没有移除事件而造成的内存溢出
点击按钮会打印出内部data-type属性的值
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>3.点击事件title>
head>
<body>
<div class="box">
<button data-type="+">+button>
<button data-type="-">-button>
<button data-type="*">*button>
<button data-type="/">/button>
div>
body>
html>
<script>
let box = document.querySelector('.box')
box.onclick=function(e){
if(e.target.tagName==='BUTTON'){
const theDataType = e.target.getAttribute('data-type')
console.log(theDataType)
}
}
script>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>拖拽title>
<style>
.box {
height: 100px;
width: 100px;
background-color: skyblue;
position: absolute;
top: 0px;
left: 0px;
}
style>
head>
<body>
<div class="box">div>
body>
html>
<script>
let box = document.querySelector(".box");
let startX=0, startY=0, endX=0, endY=0;
box.onmousedown = function (e) {
//移入到小盒子里面按下获取初始坐标
startX = e.offsetX;
startY = e.offsetY;
console.log(startX, startY);
//在整个页面,按着鼠标移动,抬起的瞬间求结束坐标
window.addEventListener("mouseup", move);
};
const move = function move(e) {
//结束坐标
endX = e.clientX;
endY = e.clientY;
//盒子最后的位置 结束坐标-初始坐标
box.style.left = endX - startX + "px";
box.style.top = endY - startY + "px";
//抬起结束后,要移除抬起事件,否则盒子就一直还跟着鼠标
window.removeEventListener("mouseup", move);
};
script>
鼠标在当前元素中的坐标替换
e.offsetX可以用e.clientX-box.offsetLeft代替
e.offsetY可以用e.clientY-box.offsetTop
box.onmousedown=function(e){//进入盒子按下的一瞬间,获取初始坐标
startX=e.offsetX;
startY=e.offsetY;
//再整个文档中移动鼠标,抬起瞬间获取结束坐标
}
//等价于
box.onmousedown = function (e) {
startX = e.clientX - box.offsetLeft;
startY = e.clientY - box.offsetTop;
};
在小盒子点击后,添加了window的mousemove事件。
在小盒子移动后,依旧使用window的mouseup事件移除mousemove对应函数及mouseup对应事件函数
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>拖拽3title>
<style>
.box {
height: 100px;
width: 100px;
background-color: skyblue;
position: absolute;
top: 0px;
left: 0px;
}
style>
head>
<body>
<div class="box">div>
body>
html>
<script>
let box = document.querySelector(".box");
let startX, startY;
box.onmousedown = function (e) {
// //移入到小盒子里面按下获取初始坐标
// startX = e.offsetX;
// startY = e.offsetY;
// 假设无法通过offsetX/offsetY获取初始坐标
startX = e.clientX - this.offsetLeft;
startY = e.clientY - this.offsetTop;
console.log(startX, startY);
//在整个页面,按着鼠标移动,抬起的瞬间求结束坐标
window.addEventListener("mousemove", move);
window.addEventListener("mouseup", up);
};
const move = function move(e) {
let html = document.documentElement || document.body;
let maxWidth = html.clientWidth - box.offsetWidth;
let maxHeight = html.clientHeight - box.offsetHeight;
//结束坐标
let endX = e.clientX;
let endY = e.clientY;
let resX = endX - startX;
resX = Math.max(0, resX);
resX = Math.min(maxWidth, resX);
let resY = endY - startY;
resY = Math.max(0, resY);
resY = Math.min(maxHeight, resY);
//盒子最后的位置 结束坐标-初始坐标
box.style.left = resX + "px";
box.style.top = resY + "px";
};
const up = function up(e) {
window.removeEventListener("mousemove", move);
window.removeEventListener("mouseup", up);
};
script>
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" />
<title>Documenttitle>
<style>
* {
margin: 0;
padding: 0;
}
#box {
height: 100px;
width: 100px;
background-color: pink;
position: fixed;
left: 0;
top: 0;
}
#boxtwo {
height: 200px;
width: 200px;
background-color: aqua;
position: fixed;
left: 0;
top: 200px;
}
style>
head>
<body>
<div id="box">div>
<div id="boxtwo">div>
body>
html>
<script>
let html = document.documentElement || document.body;
//每个盒子都有自己的起始坐标,结束坐标,范围值...
//给每个盒子添加 私有的属性值
function down(e) {
this.startX = e.offsetX;
this.startY = e.offsetY;
//修改this指向 call apply bind
this._move = move.bind(this);
this._up = up.bind(this);
window.addEventListener("mousemove", this._move);
window.addEventListener("mouseup", this._up);
}
function move(e) {
//console.log(this);//window
//console.log(e.target);
this.endX = e.clientX;
this.endY = e.clientY;
this.resultX = this.endX - this.startX;
this.resultY = this.endY - this.startY;
this.maxW = html.clientWidth - this.offsetWidth;
this.maxH = html.clientHeight - this.offsetHeight;
this.resultX = this.resultX >= this.maxW ? this.maxW : this.resultX <= 0 ? 0 : this.resultX;
this.resultY = this.resultY >= this.maxH ? this.maxH : this.resultY <= 0 ? 0 : this.resultY;
this.style.left = this.resultX + "px";
this.style.top = this.resultY + "px";
}
function up() {
window.removeEventListener("mousemove", this._move);
window.removeEventListener("mouseup", this._up);
}
box.addEventListener("mousedown", down);
boxtwo.addEventListener("mousedown", down);
script>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Documenttitle>
<style>
.box {
width: 700px;
margin: 50px auto;
height: 400px;
display: flex;
}
.leftbox {
width: 300px;
height: 300px;
position: relative;
}
.leftbox img {
width: 300px;
height: 300px;
}
.leftbox .mark {
display: none;
width: 100px;
height: 100px;
background-color: red;
opacity: 0.5;
position: absolute;
left: 0;
top: 0;
}
.rightbox {
display: none;
width: 400px;
height: 400px;
overflow: hidden;
position: relative;
}
.rightbox img {
/* width:1200px;
height:1200px; */
position: absolute;
left: 0;
top: 0;
}
style>
head>
<body>
<div class="box">
<div class="leftbox">
<img src="images/1.jpg" alt="" />
<div class="mark">div>
div>
<div class="rightbox">
<img src="images/2.jpg" alt="" />
div>
div>
body>
html>
<script>
(function () {
//1.求出大图片的高度和宽度
let leftbox = document.querySelector(".leftbox"); //左侧盒子
let mark = document.querySelector(".mark"); //遮罩层
let rightbox = document.querySelector(".rightbox"); //右侧盒子
let bigimg = document.querySelector(".rightbox img"); //大图片
function getwh(ele, attr) {
return parseFloat(window.getComputedStyle(ele)[attr]);
}
//左侧盒子 高度和宽度
let leftboxW = leftbox.offsetWidth;
let leftboxH = leftbox.offsetHeight;
//右侧盒子 高度和宽度
//隐藏的盒子无法通过offsetWidth/offsetHeight 求值,默认为0
let rightboxW = getwh(rightbox, "width");
let rightboxH = getwh(rightbox, "height");
//遮罩层 高度和宽度
let markW = getwh(mark, "width");
let markH = getwh(mark, "height");
//设置大图片的高度和宽度
bigimg.style.width = (rightboxW / markW) * leftboxW + "px";
bigimg.style.height = (rightboxH / markH) * leftboxH + "px";
//移入盒子,mark和右侧盒子显示
leftbox.onmouseenter = function () {
mark.style.display = "block";
rightbox.style.display = "block";
};
//移出盒子,mark和右侧盒子隐藏
leftbox.onmouseleave = function () {
mark.style.display = "none";
rightbox.style.display = "";
};
//鼠标在左侧小盒移动,mark也移动
leftbox.onmousemove = function (e) {
let cx = e.clientX;
let cy = e.clientY;
let maxW = leftboxW - markW;
let maxH = leftboxH - markH;
let resX = cx - markW / 2 - leftbox.offsetLeft;
let resY = cy - markH / 2 - leftbox.offsetTop;
resX = resX < 0 ? 0 : resX > maxW ? maxW : resX;
resY = resY < 0 ? 0 : resY > maxH ? maxH : resY;
//移动红色遮罩层
mark.style.left = resX + "px";
mark.style.top = resY + "px";
//移动大图片---按照比率
bigimg.style.left = "-" + (rightboxW / markW) * resX + "px";
bigimg.style.top = "-" + (rightboxH / markH) * resY + "px";
};
})();
script>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Documenttitle>
<style>
.box {
--min-image-width: 300px;
--min-image-height: 300px;
--mark-width: 100px;
--mark-height: 100px;
--scale: 4;
margin: 250px;
display: flex;
position: relative;
}
.box .left-box {
width: var(--min-image-width);
height: var(--min-image-height);
position: relative;
}
.box .left-box img {
width: var(--min-image-width);
height: var(--min-image-height);
}
.box .left-box .mark {
display: none;
width: var(--mark-width);
height: var(--mark-height);
background-color: red;
opacity: 50%;
position: absolute;
left: 0px;
top: 0px;
}
.box .right-box {
display: none;
width: calc(var(--mark-width) * var(--scale));
height: calc(var(--mark-height) * var(--scale));
overflow: hidden;
position: absolute;
left: var(--min-image-width);
top: 0px;
}
.box .right-box img {
width: calc(var(--min-image-width) * var(--scale));
height: calc(var(--min-image-height) * var(--scale));
position: absolute;
left: 0px;
top: 0px;
}
style>
head>
<body>
<div class="box">
<div class="left-box">
<img
src="https://cdn.cnbj0.fds.api.mi-img.com/b2c-shopapi-pms/pms_1672220519.85821941.png"
alt="大图"
/>
<div class="mark">div>
div>
<div class="right-box">
<img
src="https://cdn.cnbj0.fds.api.mi-img.com/b2c-shopapi-pms/pms_1672220519.85821941.png"
alt="大图"
/>
div>
div>
body>
<script>
(function () {
//1. 未出图片的高度和宽度
let box = document.querySelector(".box");
let leftBox = box.querySelector(".left-box");
let mark = leftBox.querySelector(".mark");
let rightBox = box.querySelector(".right-box");
let bigImage = rightBox.querySelector("img");
//左侧盒子 高度和宽度
let leftBoxWidth = leftBox.offsetWidth;
let leftBoxHeight = leftBox.offsetHeight;
const getWH = function getWH(ele, attr) {
// console.log(window.getComputedStyle(ele)[attr]);
return parseInt(window.getComputedStyle(ele)[attr]) || 0;
};
//右侧盒子 高度和宽度
// 隐藏的盒子无法通过offsetWidth/offsetHeight求值,默认为0
let rightBoxWidth = getWH(rightBox, "width");
let rightBoxHeight = getWH(rightBox, "height");
let markWidth = getWH(mark, "width");
let markHeight = getWH(mark, "height");
let bigImageWidth = (rightBoxWidth / markWidth) * leftBoxWidth;
let bigImageHeight = (rightBoxHeight / markHeight) * leftBoxHeight;
// console.log(bigImageWidth, bigImageHeight);
bigImage.style.width = `${bigImageWidth}px`;
bigImage.style.height = `${bigImageHeight}px`;
leftBox.onmouseenter = function () {
mark.style.display = "block";
rightBox.style.display = "block";
};
leftBox.onmouseleave = function () {
mark.style.display = "none";
rightBox.style.display = "none";
};
leftBox.onmousemove = function (e) {
let cx = e.clientX;
let cy = e.clientY;
let maxWidth = leftBoxWidth - markWidth;
let maxHeight = leftBoxHeight - markHeight;
let resX = cx - markWidth / 2 - leftBox.getBoundingClientRect().left;
let resY = cy - markHeight / 2 - leftBox.getBoundingClientRect().top;
console.log(cx, cy, resX, resY, maxWidth, maxHeight);
resX = resX < 0 ? 0 : resX > maxWidth ? maxWidth : resX;
resY = resY < 0 ? 0 : resY > maxHeight ? maxHeight : resY;
mark.style.left = `${resX}px`;
mark.style.top = `${resY}px`;
bigImage.style.left = `-${resX * (rightBoxWidth / markWidth)}px`;
bigImage.style.top = `-${resY * (rightBoxHeight / markHeight)}px`;
};
})();
script>
html>