用 JS 在点击附近触摸拖放定位
Touch drag-and-drop positioning near tap with JS
我想制作在我的页面上拖放一些元素的功能。当我使用下面的代码时,元素通过触摸移动,但它并没有停留在我点击的手指附近(例如在元素的中心或 left/right 底部),而是从手指移动到右下角。我想要的 - 是能够通过我点击的点拖动它来移动元素。
function touchStart(e) {
e.preventDefault();
var whichArt = e.target;
resetZ();
whichArt.style.zIndex = 10;
}
function touchMove(e) {
e.preventDefault();
var dragElem = e.target;
var touch = e.touches[0];
var positionX = touch.pageX;
var positionY = touch.pageY;
dragElem.style.left = positionX + 'px';
dragElem.style.top = positionY + 'px';
}
document.querySelector('body').addEventListener('touchstart', touchStart, false);
document.querySelector('body').addEventListener('touchmove', touchMove, false);
<!--elements I want to drag-->
<img draggable="true" id="one" src="images/one.svg" style="position: absolute; left: 50px; top: 120px; z-index: 3;">
<img draggable="true" id="two" src="images/two.svg" style="position: absolute; left: 367px; top: 150px; z-index: 3;">
我也尝试过用不同的东西来计算左右位置,但是失败了,例如:
var moveOffsetX = dragElem.offsetLeft - touch.pageX;
var moveOffsetY = dragElem.offsetTop - touch.pageY;
var positionX = touch.pageX - moveOffsetX; /* + also tried*/
var positionY = touch.pageY - moveOffsetY; /* + also tried*/
那么如何实现正确的行为呢?
这是因为元素的锚点在左上角。
在你的 touchMove
函数中试试这个:
dragElem.style.left = positionX - dragElem.width / 2 + 'px';
dragElem.style.top = positionY - dragElem.height / 2 + 'px';
这里是working fiddle。您可以使用开发者工具中的设备模式在 chrome 上进行测试。
PS。你应该有一个 touchend
事件来重新初始化 z-index
(如果你还没有这样做的话)。
编辑
因此,在 touchstart
事件中,您必须保存元素的锚点(用户触摸元素的位置)。
为此,您可以使用 getBoundingClientRect()
函数。这比依赖样式 top/left 属性要好,因为它们可能未指定:
var elementRect = whichArt.getBoundingClientRect();
anchor = {
top: touch.pageY - elementRect.top,
left: touch.pageX - elementRect.left
};
然后你使用这个 anchor
来计算 top/left 而不是元素的中心(正如我最初想的那样)。
我想制作在我的页面上拖放一些元素的功能。当我使用下面的代码时,元素通过触摸移动,但它并没有停留在我点击的手指附近(例如在元素的中心或 left/right 底部),而是从手指移动到右下角。我想要的 - 是能够通过我点击的点拖动它来移动元素。
function touchStart(e) {
e.preventDefault();
var whichArt = e.target;
resetZ();
whichArt.style.zIndex = 10;
}
function touchMove(e) {
e.preventDefault();
var dragElem = e.target;
var touch = e.touches[0];
var positionX = touch.pageX;
var positionY = touch.pageY;
dragElem.style.left = positionX + 'px';
dragElem.style.top = positionY + 'px';
}
document.querySelector('body').addEventListener('touchstart', touchStart, false);
document.querySelector('body').addEventListener('touchmove', touchMove, false);
<!--elements I want to drag-->
<img draggable="true" id="one" src="images/one.svg" style="position: absolute; left: 50px; top: 120px; z-index: 3;">
<img draggable="true" id="two" src="images/two.svg" style="position: absolute; left: 367px; top: 150px; z-index: 3;">
我也尝试过用不同的东西来计算左右位置,但是失败了,例如:
var moveOffsetX = dragElem.offsetLeft - touch.pageX;
var moveOffsetY = dragElem.offsetTop - touch.pageY;
var positionX = touch.pageX - moveOffsetX; /* + also tried*/
var positionY = touch.pageY - moveOffsetY; /* + also tried*/
那么如何实现正确的行为呢?
这是因为元素的锚点在左上角。
在你的 touchMove
函数中试试这个:
dragElem.style.left = positionX - dragElem.width / 2 + 'px';
dragElem.style.top = positionY - dragElem.height / 2 + 'px';
这里是working fiddle。您可以使用开发者工具中的设备模式在 chrome 上进行测试。
PS。你应该有一个 touchend
事件来重新初始化 z-index
(如果你还没有这样做的话)。
编辑
因此,在 touchstart
事件中,您必须保存元素的锚点(用户触摸元素的位置)。
为此,您可以使用 getBoundingClientRect()
函数。这比依赖样式 top/left 属性要好,因为它们可能未指定:
var elementRect = whichArt.getBoundingClientRect();
anchor = {
top: touch.pageY - elementRect.top,
left: touch.pageX - elementRect.left
};
然后你使用这个 anchor
来计算 top/left 而不是元素的中心(正如我最初想的那样)。