Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是/否-是否有办法使用纯SVG工具改进鼠标拖动?_Svg_Mouse_Drag - Fatal编程技术网

是/否-是否有办法使用纯SVG工具改进鼠标拖动?

是/否-是否有办法使用纯SVG工具改进鼠标拖动?,svg,mouse,drag,Svg,Mouse,Drag,所以我花了一些时间来处理纯SVG元素(没有外部库) 一般来说,所有这些都可以工作,但对于快速移动的鼠标来说,有一个棘手的问题: -当用户将可拖动的SVG元素移到靠近其边缘的位置时 -然后拖动(mousemove)这样的拖动太快了 -鼠标“丢失”了可拖动的鼠标 这里将更详细地描述该问题: 在这里,作者还试图利用mouseout事件修复UX: 我在这里复制了上面的代码片段: 我的问题是: 当鼠标移动太快时,是否没有其他方法(由纯SVG提供)来防止SVG元素的这种“丢失” 我试图解决这个问题的方法是

所以我花了一些时间来处理纯SVG元素(没有外部库)

一般来说,所有这些都可以工作,但对于快速移动的鼠标来说,有一个棘手的问题: -当用户将可拖动的SVG元素移到靠近其边缘的位置时 -然后拖动(mousemove)这样的拖动太快了 -鼠标“丢失”了可拖动的鼠标

这里将更详细地描述该问题: 在这里,作者还试图利用mouseout事件修复UX:

我在这里复制了上面的代码片段:

我的问题是:

当鼠标移动太快时,是否没有其他方法(由纯SVG提供)来防止SVG元素的这种“丢失”

我试图解决这个问题的方法是: -检测(以某种方式)在未完成拖动的情况下发生mouseout事件。 -如果是这样(我们检测到了“断开连接”)-将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")