javascript - 可调整大小的对象无法正常工作本机js
问题描述
在我的项目中,用户可以根据需要创建任意数量的对象并调整它们的大小。但是有一些错误会导致调整大小变得非常快。当用户创建一个对象时,调整它的大小,然后创建第二个对象并调整它的大小,调整第二个对象的大小后回到第一个对象的大小,调整第一个对象的大小比鼠标移动速度快。
//create
function create() {
const workArea = document.querySelector('.work-area');
let divParent = document.createElement("div");
divParent.className = "divParent";
let div = document.createElement("div");
div.className = "div";
divParent.appendChild(div);
workArea.appendChild(divParent);
var resizerNE = document.createElement("div");
resizerNE.className = "resizerNE";
resizerNE.classList.add("resizer");
var resizerSE = document.createElement("div");
resizerSE.className = "resizerSE";
resizerSE.classList.add("resizer");
var resizerSW = document.createElement("div");
resizerSW.className = "resizerSW";
resizerSW.classList.add("resizer");
var resizerNW = document.createElement("div");
resizerNW.className = "resizerNW";
resizerNW.classList.add("resizer");
divParent.appendChild(resizerNE);
divParent.appendChild(resizerSE);
divParent.appendChild(resizerSW);
divParent.appendChild(resizerNW);
//resize
let el;
const resizer = document.querySelectorAll(".resizer");
resizer.forEach(function(thisresizer) {
thisresizer.addEventListener("mousedown", function() {
el = this.parentNode;
});
});
let isResizing = false;
const resizers = document.querySelectorAll(".resizer");
let currentResizer;
for (let resizer of resizers) {
resizer.addEventListener("mousedown", mousedown);
function mousedown(e) {
currentResizer = e.target;
isResizing = true;
//console.log(el);
let prevX = e.clientX;
let prevY = e.clientY;
window.addEventListener("mousemove", mousemove);
window.addEventListener("mouseup", mouseup);
function mousemove(e) {
const rect = el.getBoundingClientRect();
if (currentResizer.classList.contains("resizerSE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerSW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.height = rect.height - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerNE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerNW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerN")) {
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerS")) {
el.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
}
el.children[0].style.width = el.style.width;
el.children[0].style.height = el.style.height;
//console.log("prevX: " + prevX + " prevY: " + prevY);
prevX = e.clientX;
prevY = e.clientY;
}
function mouseup() {
window.removeEventListener("mousemove", mousemove);
window.removeEventListener("mouseup", mouseup);
isResizing = false;
}
}
}
}
.work-area{
width: 100%;
height: 100vh;
}
.divParent{
width: 100px;
height: 100px;
position: absolute;
background:black
}
.div{
background: #555555;
}
.resizer {
width: 12px;
height: 12px;
position: absolute;
z-index: 99999999;
border: 1px solid #2872c7;
border-radius: 10px;
background: #f2f2f2;
box-sizing: border-box;
display: block;
}
.resizerSE {
right: -6px;
bottom: -6px;
cursor: se-resize;
}
.resizerNE {
top: -6px;
right: -6px;
cursor: ne-resize;
}
.resizerSW {
left: -6px;
bottom: -6px;
cursor: sw-resize;
}
.resizerNW {
left: -6px;
top: -6px;
cursor: nw-resize;
}
<button onclick="create()">Create</button>
<div class="work-area">
</div>
解决方案
最后
我花了一个多小时寻找解决问题的方法
每次创建对象时,您都会将侦听器添加到以前的调整大小,这 就是为什么每个新对象都可以更快地调整以前的大小
换句话说,浏览器在每个 mousemove 事件中移动更多步数
唯一的变化是
const resizers = document.querySelectorAll(".resizer");
至
const resizers = divParent.querySelectorAll(".resizer");
同样在我的回答中,我重新排列了您的代码,使其更易于阅读和更小
//create
function create() {
const workArea = document.querySelector(".work-area");
let divParent = document.createElement("div");
divParent.className = "divParent";
workArea.appendChild(divParent);
NewDiv = cls => {
let elm = document.createElement("div");
elm.className = cls;
divParent.appendChild(elm);
};
let div = NewDiv("div");
let resizerNE = NewDiv("resizerNE resizer");
let resizerSE = NewDiv("resizerSE resizer");
let resizerSW = NewDiv("resizerSW resizer");
let resizerNW = NewDiv("resizerNW resizer");
//resize
let el;
let isResizing = false;
const resizers = divParent.querySelectorAll(".resizer");
let currentResizer;
let prevX;
let prevY;
function mousedown(e) {
el = this.parentNode;
currentResizer = e.target;
isResizing = true;
prevX = e.clientX;
prevY = e.clientY;
workArea.addEventListener("mousemove", mousemove);
workArea.addEventListener("mouseup", mouseup);
}
for (let resizer of resizers) {
resizer.addEventListener("mousedown", mousedown);
}
function mousemove(e) {
if (isResizing) {
const rect = el.getBoundingClientRect();
if (currentResizer.classList.contains("resizerSE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerSW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.height = rect.height - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerNE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerNW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerN")) {
el.style.height = rect.height + (prevY - e.clientY) + "px";
el.style.top = rect.top - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerE")) {
el.style.width = rect.width - (prevX - e.clientX) + "px";
} else if (currentResizer.classList.contains("resizerS")) {
el.style.height = rect.height - (prevY - e.clientY) + "px";
} else if (currentResizer.classList.contains("resizerW")) {
el.style.width = rect.width + (prevX - e.clientX) + "px";
el.style.left = rect.left - (prevX - e.clientX) + "px";
}
el.children[0].style.width = el.style.width;
el.children[0].style.height = el.style.height;
//console.log("prevX: " + prevX + " prevY: " + prevY);
prevX = e.clientX;
prevY = e.clientY;
}
}
function mouseup() {
isResizing = false;
workArea.removeEventListener("mouseup", mouseup);
workArea.removeEventListener("mousemove", mousemove);
}
}
.work-area {
width: 100%;
height: 100vh;
}
.divParent {
width: 100px;
height: 100px;
position: absolute;
background: black;
}
.div {
background: #555555;
}
.resizer {
width: 12px;
height: 12px;
position: absolute;
z-index: 99999999;
border: 1px solid #2872c7;
border-radius: 10px;
background: #f2f2f2;
box-sizing: border-box;
display: block;
}
.resizerSE {
right: -6px;
bottom: -6px;
cursor: se-resize;
}
.resizerNE {
top: -6px;
right: -6px;
cursor: ne-resize;
}
.resizerSW {
left: -6px;
bottom: -6px;
cursor: sw-resize;
}
.resizerNW {
left: -6px;
top: -6px;
cursor: nw-resize;
}
<body>
<button onclick="create()">Create</button>
<div class="work-area"></div>
</body>
推荐阅读
- c++ - 为什么 &a 和 c++ 中的静态数组相同?
- python - 如何从数据框中删除多索引级别等于 NaN(无值)的列
- python - 使用python仅在趋势和残差中分解时间序列
- forms - SAPUI5 - 读取动态创建的表单
- mysql - 将 .txt.gz 文件的目录加载到 MySQL
- bash - SVN 验证未检测到损坏的修订
- java - 如何在 Java 中将数组 20 字节大小调整为 16 字节
- c# - 将贷款+利息资本化公式的循环引用从 VBA 转换为 C#
- google-slides-api - Google Slides API - 如何通过 API 更改主题
- microsoft-graph-api - Microsoft Graph API:DELETE / PATCH 事件实例