我有一个mousemove
事件,我添加到mousedown
事件的元素,然后我在mouseup
事件中将其删除。
在鼠标移动事件中我触发此功能,其中我减去X和Y的一半宽度和高度以使图像居中:
dragImage(e) {
const width = this.getStyle(e.target, 'width').split('p')[0];
const height = this.getStyle(e.target, 'height').split('p')[0];
const X = e.pageX - (window.innerWidth / 2 - window.innerHeight / 2) || e.touches[0].clientX;
const Y = e.pageY || e.touches[0].clientY;
const stopTop = Y - (height / 2) > 0;
const stopBottom = Y + (height / 2) < this.getStyle(e.target.parentNode, 'height').split('p')[0];
const stopLeft = X - (width / 2) > 0;
const stopRight = X + (width / 2) < this.getStyle(e.target.parentNode, 'width').split('p')[0];
const stopTop = Y - (height / 2) > 0;
const stopBottom = Y + (height / 2) < this.getStyle(e.target.parentNode, 'height').split('p')[0];
const stopLeft = X - (width / 2) > 0;
const stopRight = X + (width / 2) < this.getStyle(e.target.parentNode, 'width').split('p')[0];
// check if element is within vertical bounds
if (stopTop) {
this.image.style.bottom = '';
this.image.style.top = '0px';
} else if (stopBottom) {
this.image.style.top = '';
this.image.style.bottom = '0px';
} else {
this.image.style.bottom = '';
this.image.style.top = `${Y}px`;
}
// check if element is within horizontal bounds
if (stopLeft) {
this.image.style.right = '';
this.image.style.left = '0px';
} else if (stopRight) {
this.image.style.left = '';
this.image.style.right = '0px';
} else {
this.image.style.right = '';
this.image.style.left = `${X}px`;
}
return false;
}
我已经尝试从pageX
和pageY
中减去元素的偏移量,并且它在那里得到了一半,但被拖动的元素因为每隔一个X / Y值关闭而闪烁,因此值可以是900,500,900,500等。
可能导致价值变化的原因是什么?我过度复杂化了什么?我所要做的就是拖动一个图像,而不是将它放在指针周围,保持在一个边界内。
感谢。
E - 添加更多代码以澄清:
我在构造函数中添加了第一组mousedown,mouseup和mouseleave事件:
if (this.isMobile) {
this.image.addEventListener('touchstart', e => this.enableDrag(e));
this.image.addEventListener('touchend', e => this.disableDrag(e));
this.image.addEventListener('touchcancel', () => this.disableDrag());
} else {
this.image.addEventListener('mousedown', e => this.enableDrag(e));
this.image.addEventListener('mouseup', e => this.disableDrag(e));
this.image.addEventListener('mouseleave', () => this.disableDrag());
this.image.addEventListener('click', e => e.cancelBubble = true);
}
这些事件添加和删除以下功能,该功能可以进行拖动:
enableDrag(e) {
e = e || window.event;
e.cancelBubble = true;
e.preventDefault();
if (this.isMobile) {
this.image.addEventListener('touchmove', this.dragEvent);
} else {
this.image.addEventListener('mousemove', this.dragEvent);
}
}
disableDrag() {
if (this.isMobile) {
this.image.removeEventListener('touchmove', this.dragEvent);
} else {
this.image.removeEventListener('mousemove', this.dragEvent);
}
}
答案 0 :(得分:1)
基于此:&#34;可能导致价值变化的原因是什么?我过度复杂化了什么?我所要做的就是拖动一个图像,而不是将它放在指针周围,保持在一个边界内。&#34;,我提出三个建议:
top
和left
属性,忘记bottom
和right
mousedown
事件中计算它,并在此处使用它。考虑到这一点,您可以简化代码:
dragImage(e) {
var imageBoundaries = this.image.getBoundingClientRect();
var containerWidth = this.getStyle(e.target.parentNode, 'width').split('p')[0];
var containerHeight = this.getStyle(e.target.parentNode, 'height').split('p')[0];
const X = (e.pageX || e.touches[0].clientX) - offsetX; /* where offsetX is defined as where the user initially clicked on the image in the mousedown event */
const Y = (e.pageY || e.touches[0].clientY) - offsetY; /* ditto */
if X <= 0 {
// hit the left boundary
X = 0
} else if X + imageBoundaries.width >= containerWidth {
// hit the right boundary
X = containerWidth - imageBoundaries.width
}
if Y <= 0 {
// hit the top boundary
Y = 0
} else if Y + imageBoundaries.height >= containerHeight {
// hit the bottom boundary
Y = containerHeight - imageBoundaries.height
}
this.image.style.left = `${X}px`;
this.image.style.top = `${Y}px`;
return false;
}
这会将图像夹到窗口的边界(假设您希望始终看到整个图像)。如果你愿意让图像稍微移出视口,你可以摆弄if条件。
最后,众所周知,拖放是很难做到的,我通常会为了这个功能而跑到第三方。像Dragula之类的东西是设置我见过的拖放最常见情况的一个例子。当然,如果这是为了学习那么是的,滚动你自己:)