大家好,我有以下问题:
每当我拖动一个元素时,它都会闪烁,看起来非常烦人。我找不到问题的根源。
下面是我的代码片段:
moveElement(element, e) {
let clientX = e.clientX;
let clientY = e.clientY;
let offsetX = e.offsetX;
let offsetY = e.offsetY;
let height = element.getBoundingClientRect().height;
let width = element.getBoundingClientRect().width;
window.requestAnimationFrame(function() {
element.style.setProperty("left", clientX - (width - offsetX) + "px");
element.style.setProperty("top", clientY - (height - offsetY) + "px");
});
}下面是他的完整代码:
class Dragger{
constructor() {
this.drags = [];
this.drops = [];
this.mover = null;
this.collectDragAndDrop();
}
dragItem(element) {
element.style.setProperty("position", "fixed");
this.mover = this.moveElement.bind(null, element);
element.addEventListener("mousemove", this.mover);
}
moveElement(element, e) {
let clientX = e.clientX;
let clientY = e.clientY;
let offsetX = e.offsetX;
let offsetY = e.offsetY;
let height = element.getBoundingClientRect().height;
let width = element.getBoundingClientRect().width;
window.requestAnimationFrame(function() {
element.style.setProperty("left", clientX - (width - offsetX) + "px");
element.style.setProperty("top", clientY - (height - offsetY) + "px");
});
}
dropItem(element) {
element.removeEventListener("mousemove", this.mover);
}
collectDragAndDrop() {
document.querySelectorAll("[drag]").forEach(element => {
let name = element.attributes.drag.nodeValue;
let findDup = this.drags.some(el => el.name === name);
if (findDup) throw Error("Duplicated drag attribute: " + name);
this.drags.push({
element,
name
});
element.addEventListener("mousedown", this.dragItem.bind(this, element));
element.addEventListener("mouseup", this.dropItem.bind(this, element));
});
}
}
new Dragger(); .box1 {
background: black;
width: 100px;
height: 100px;
color: white;
}
.box2 {
background: red;
width: 100px;
height: 100px;
position: fixed;
right: 100px;
}<div class="box1" drag="test"></div>
<div class="box2" drag="test2"></div>
有没有人能告诉我为什么它会闪烁这么多?
发布于 2020-07-15 22:09:08
你的数学很不靠谱。您只考虑了当前的鼠标位置,而没有计算已经发生的移动量。您的框移动的唯一原因是因为函数正在等待动画帧,所以在等待期间,这些坐标会发生一些变化。
您还应该考虑到,如果鼠标向上移动时鼠标不再位于元素上,则元素将不会获得事件,因此当您将鼠标移回元素上时,元素将继续拖动。最好设置一个跟踪鼠标状态的标志。
var isMouseDown = false;
addEventListener("mousedown", ()=>isMouseDown = true);
addEventListener("mouseup", ()=>isMouseDown = false);
document.querySelectorAll("[drag]").forEach(element=>{
element.addEventListener("mousemove", e=>{
if(!isMouseDown) return;
requestAnimationFrame(function() {
var rect = element.getBoundingClientRect();
element.style.left = rect.x + e.movementX + "px";
element.style.top = rect.y + e.movementY + "px";
});
});
});.box1 {
background: black;
width: 100px;
height: 100px;
color: white;
position: absolute
}
.box2 {
background: red;
width: 100px;
height: 100px;
position: fixed;
right: 100px;
}<div class="box1" drag="test"></div>
<div class="box2" drag="test2"></div>
https://stackoverflow.com/questions/62915549
复制相似问题