是/否-是否有办法使用纯SVG工具改进鼠标拖动?
所以我花了一些时间来处理纯SVG元素(没有外部库) 一般来说,所有这些都可以工作,但对于快速移动的鼠标来说,有一个棘手的问题: -当用户将可拖动的SVG元素移到靠近其边缘的位置时 -然后拖动(mousemove)这样的拖动太快了 -鼠标“丢失”了可拖动的鼠标 这里将更详细地描述该问题: 在这里,作者还试图利用mouseout事件修复UX: 我在这里复制了上面的代码片段: 我的问题是: 当鼠标移动太快时,是否没有其他方法(由纯SVG提供)来防止SVG元素的这种“丢失” 我试图解决这个问题的方法是: -检测(以某种方式)在未完成拖动的情况下发生mouseout事件。 -如果是这样(我们检测到了“断开连接”)-将SVG元素与当前鼠标位置重新连接 这有什么原因不起作用吗? 代码:是/否-是否有办法使用纯SVG工具改进鼠标拖动?,svg,mouse,drag,Svg,Mouse,Drag,所以我花了一些时间来处理纯SVG元素(没有外部库) 一般来说,所有这些都可以工作,但对于快速移动的鼠标来说,有一个棘手的问题: -当用户将可拖动的SVG元素移到靠近其边缘的位置时 -然后拖动(mousemove)这样的拖动太快了 -鼠标“丢失”了可拖动的鼠标 这里将更详细地描述该问题: 在这里,作者还试图利用mouseout事件修复UX: 我在这里复制了上面的代码片段: 我的问题是: 当鼠标移动太快时,是否没有其他方法(由纯SVG提供)来防止SVG元素的这种“丢失” 我试图解决这个问题的方法是
var click=false;//用于指示何时单击形状的标志
变量clickX,clickY;//第一次单击时存储光标位置
var moveX=0,moveY=0;//跟踪整体转型
var lastMoveX=0,lastMoveY=0;//存储以前的转换(移动)
功能鼠标向下(evt){
evt.preventDefault();//Firefox需要允许正确拖动
单击=真;
clickX=evt.clientX;
clickY=evt.clientY;
setAttribute(“填充”、“绿色”);
}
功能移动(evt){
evt.preventDefault();
如果(单击){
moveX=lastMoveX+(evt.clientX–clickX);
moveY=lastmovy+(evt.clientY–clickY);
setAttribute(“transform”、“translate”(“+moveX+”,“+moveY+”));
}
}
函数endMove(evt){
单击=false;
lastMoveX=moveX;
lastMoveY=moveY;
setAttribute(“填充”、“灰色”);
}
缺少代码中最重要的部分,即如何或更具体地在哪个元素上注册事件
防止此问题的基本方法是在最外层的svg元素上注册mousemove和mouseup事件,而不是在要拖动的元素上注册
svg.addEventListener("mousemove", move)
svg.addEventListener("mouseup", endMove)
开始拖动时,在svg元素上注册事件,完成后取消注册
svg.removeEventListener("mousemove", move)
svg.removeListener("mouseup", endMove)
您必须存储当前正在拖动的元素,以便它在其他事件处理程序中可用
另外,我要做的是将指针事件设置为拖动对象上的“无”
元素,以便您可以对拖动元素下的鼠标事件作出反应(例如,查找放置目标…)
但当拖动完成时,不要忘记将其设置回合理的位置
evt.target.setAttribute("pointer-events", "all")
var click=false;//用于指示何时单击形状的标志
变量clickX,clickY;//第一次单击时存储光标位置
var moveX=0,
moveY=0;//跟踪整体转型
var lastMoveX=0,
lastMoveY=0;//存储以前的转换(移动)
var currentTarget=null
功能鼠标向下(evt){
evt.preventDefault();//Firefox需要允许正确拖动
单击=真;
clickX=evt.clientX;
clickY=evt.clientY;
setAttribute(“填充”、“绿色”);
//在最外层的SVG元素上注册移动事件
currentTarget=evt.target
svg.addEventListener(“mousemove”,move)
svg.addEventListener(“mouseup”,endMove)
setAttribute(“指针事件”,“无”)
}
功能移动(evt){
evt.preventDefault();
如果(单击){
moveX=lastMoveX+(evt.clientX-clickX);
moveY=lastmovy+(evt.clientY-clickY);
setAttribute(“transform”、“translate”(“+moveX+”,“+moveY+”));
}
}
函数endMove(evt){
单击=false;
lastMoveX=moveX;
lastMoveY=moveY;
currentTarget.setAttribute(“填充”、“灰色”);
removeEventListener(“mousemove”,move)
removeEventListener(“mouseup”,endMove)
currentTarget.setAttribute(“指针事件”、“全部”)
}
evt.clientY–clickY
这些都是合法的javascript缺点…嘿,谢谢你的回答。你能帮我理解(扩展一下你的答案)为什么“动态”分配和删除侦听器很重要吗?这会解决鼠标移动“断开”的问题吗?因为事件处理程序位于svg元素上,所以会一直触发移动事件。在静态处理程序中,您可以在拖动代码周围放置if语句,但如果不需要,通常不使用if语句更为优雅。这种方式对资源更加友好,并且将代码与演示分离。您可以在任何SVG上使用此代码,而无需触摸SVG代码本身。。。解决“粘性”“断开连接”问题的方法是,处理程序在最外层的svg元素上注册,而不是在拖动的元素上注册。我已经在答案中强调了这些部分…顺便说一句,您的代码片段工作得非常好。所以我猜动态侦听器+其他项确实可以让SVG获得非常好的鼠标行为!太棒了,谢谢你的回答-对我的项目非常有帮助!Holger,很抱歉打扰您,但是基于您的代码,我无法解决一个小的细微差别-我试图将另一个侦听器添加到Dragable对象中-dblclick-但我没有做到。这种方式不支持双击有什么原因吗?
evt.target.setAttribute("pointer-events", "all")