【发布时间】:2020-12-21 06:23:42
【问题描述】:
我在svg 元素中有几个svg use 元素,touchstart/move/end 的事件处理程序附加到svg 元素。当用户触摸屏幕上的svg use 元素并四处移动手指时,该元素会根据需要在屏幕上移动。
//Exact code in fiddle is different, this is example
<svg id="parent" viewBox="0 0 1000 1000">
<use href="test.svg" width="100" height="100" x="100" y="100">
<use href="test2.svg" width="100" height="100" x="100" y="100">
</svg>
//Exact code in fiddle is different, this is example
let parentSVG = document.getElementById("parent");
parentSVG.addEventListener('touchstart', Handle_DragStart); //mousedown too
parentSVG.addEventListener('touchmove', Handle_Drag); //mousemove too
parentSVG.addEventListener('touchend', Handle_DragEnd); //mouseup too
问题是我希望拖动的元素始终绘制在其他元素之上,并且元素按 DOM 顺序绘制(DOM 中的第一个元素在前)。为了处理这个问题,在我的touchstart 事件处理程序中,我将用户通过appendChild() 触摸的元素移动到列表的末尾:
//Exact code in fiddle is different, this is example
let mid_move = false;
function Handle_DragStart (event)
{
//Needed to ignore other touch events while dragging
if(mid_move)
return;
mid_move = true;
//The event.target is the svg use element.
//It is already attached to the parentSVG.
//This just moves it to the end of the list of children.
parentSVG.appendChild(event.target);
}
这对mousedown 和mousemove 来说就像一个魅力,但对touchstart 和touchmove 却不是。完成此操作后,touchmove 事件直到我第二次触摸屏幕才会触发,大概是因为 touchstart 处理程序中的 appendChild() 调用此时没有改变任何内容?
我是否使活动无效?这种情况应该怎么处理?
编辑:
JSFiddle example. //将 append_child 设置为 true/false 以查看行为
【问题讨论】:
-
请提供minimum reproducible example,即提供简单样本
test.svg和test2.svg -
如果您有兴趣,@JanStránský 添加了一个工作示例。
-
有趣。我玩过你的例子,
use在appendChild之后,touchevents 不起作用。我试图用setTimout推迟appendChild,工作得很好,直到DOM 发生变化。但是,它适用于“普通”rect。是例如使用隐形封面并根据拖动的封面调整可见元素的位置是否适合您? -
好吧,我在屏幕上有 32 个可拖动元素。我不知道这会带来什么样的性能冲击,但我当然可以尝试一下。不过,我是 javascript 的新手,想知道这些事件发生了什么。您可能会认为,由于处理程序附加到后台,因此不会受到影响...
-
从描述我不会害怕性能
标签: javascript svg events appendchild touchmove