gpt4 book ai didi

javascript - 为什么使用此功能拖动一个元素时两个元素都会移动?

转载 作者:行者123 更新时间:2023-11-30 09:13:36 25 4
gpt4 key购买 nike

我正在尝试制作一个带有 2 个可拖动 handle 的范围 slider 。它仍处于早期阶段,此时我正在尝试让两个 handle 在拖动时独立移动。

但是,我遇到的问题是,如果我将事件处理程序绑定(bind)到 document,当一个被拖动时,两个句柄会一起移动。如果我绑定(bind)到通过选择器参数(句柄本身)传入的元素,则两个句柄独立移动,但只有当鼠标指针位于该元素的范围内时才起作用,这不是一个好的行为。

这是我的代码。我做错了什么?

function draggable(selector, options) {
var options = options || {};
let el = document.querySelector(selector);
var mx = 0,
my = 0;
var dragging = false;
var offset = [0, 0];
var constrain = options.constrain || false;
if (options === undefined) options = [];

document.addEventListener('mousedown', function(e) {
dragging = true;
offset = {
x: el.offsetLeft - e.clientX,
y: el.offsetTop - e.clientY
};
});
document.addEventListener('mousemove', function(e) {
e.preventDefault();
mx = e.clientX;
my = e.clientY;

if (dragging) {
if (!constrain || constrain == 'x') el.style.left = (mx + offset.x) + 'px';
if (!constrain || constrain == 'y') el.style.top = (my + offset.y) + 'px';
}
});
document.addEventListener('mouseup', function(e) {
dragging = false;
});
}
var min = new draggable('#min', {
constrain: 'x'
});
var max = new draggable('#max', {
constrain: 'x'
});
body {
padding: 50px;
}

.range-input {
height: 24px;
position: relative;
}

.rail {
background: rgba(0, 0, 0, 0.5);
border-radius: 9px;
position: absolute;
top: 50%;
transform: translate3d(0, -50%, 0);
height: 9px;
width: 100%;
}

.handle {
background: #000;
border-radius: 50%;
height: 24px;
position: absolute;
top: 50%;
transform: translate3d(0, -50%, 0) scale(1);
width: 24px;
}

.handle:hover {
cursor: grab;
transform: translate3d(0, -50%, 0) scale(1.2);
}

.handle:active {
cursor: grabbing;
}

.min {
left: 0;
}

.max {
right: 0;
}
<div id="wrap" class="range-input">
<div class="rail"></div>
<div id="min" class="handle min"></div>
<div id="max" class="handle max"></div>
</div>

最佳答案

您的两个元素都在注册一个事件处理程序,该事件处理程序正在监听文档上的拖动事件。您的逻辑不包含排除项,因此在窗口中的任何位置单击并拖动操作都会触发您的逻辑。

不过,我可以看出你在试图阻止什么。我认为您想确保当鼠标在拖动操作(向上或向下)期间离开 handle 时,拖动操作会继续触发。为此,请在元素上注册您的 mousedown 事件。您仍然可以在文档中注册您的拖动事件,但将它们移动到您的 mousedown 事件处理程序中,如下所示:

function draggable(selector, options) {
var options = options || {};
let el = document.querySelector(selector);
var mx = 0,
my = 0;
var dragging = false;
var offset = [0, 0];
var constrain = options.constrain || false;
if (options === undefined) options = [];

el.addEventListener('mousedown', function(e) {
dragging = true;
offset = {
x: el.offsetLeft - e.clientX,
y: el.offsetTop - e.clientY
};
document.addEventListener('mousemove', function(e) {
e.preventDefault();
mx = e.clientX;
my = e.clientY;

if (dragging) {
if (!constrain || constrain == 'x') el.style.left = (mx + offset.x) + 'px';
if (!constrain || constrain == 'y') el.style.top = (my + offset.y) + 'px';
}
});
document.addEventListener('mouseup', function(e) {
dragging = false;
});
});
}
var min = new draggable('#min', {
constrain: 'x'
});
var max = new draggable('#max', {
constrain: 'x'
});
body {
padding: 50px;
}

.range-input {
height: 24px;
position: relative;
}

.rail {
background: rgba(0, 0, 0, 0.5);
border-radius: 9px;
position: absolute;
top: 50%;
transform: translate3d(0, -50%, 0);
height: 9px;
width: 100%;
}

.handle {
background: #000;
border-radius: 50%;
height: 24px;
position: absolute;
top: 50%;
transform: translate3d(0, -50%, 0) scale(1);
width: 24px;
}

.handle:hover {
cursor: grab;
transform: translate3d(0, -50%, 0) scale(1.2);
}

.handle:active {
cursor: grabbing;
}

.min {
left: 0;
}

.max {
right: 0;
}
<div id="wrap" class="range-input">
<div class="rail"></div>
<div id="min" class="handle min"></div>
<div id="max" class="handle max"></div>
</div>

请注意,您需要在完成拖动后注销文档事件处理程序。我没有添加那个逻辑,但这并不难。

关于javascript - 为什么使用此功能拖动一个元素时两个元素都会移动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56758858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com