jqui的draggable功能在scale修改的情况下不能正常运作?-灵析社区

小飞侠007

在使用jquery-ui的draggable功能时,若drag对象的父元素经过scale修饰调整了大小的比例,则此时的拖拽会出现拖拽对象瞬移,并且拖拽距离与鼠标距离不同的情况。

阅读量:374

点赞量:10

问AI
我找到了更为正确的做法:修改jquery-ui的源文件,使其能够适配scale修改 首先需要有一个能够获得当前页面的scale值的函数,我想这并不困难,直接来看如何修改这个源文件吧! 在jquery-ui中搜索:_mouseDrag: function( event, noPropagation ) { 如果没有意外的话,您会找到这样一个函数: _mouseDrag: function( event, noPropagation ) { // reset any necessary cached properties (see #5009) if ( this.hasFixedAncestor ) { this.offset.parent = this._getParentOffset(); } //Compute the helpers position this.position = this._generatePosition( event, true ); this.positionAbs = this._convertPositionTo( "absolute" ); //Call plugins and callbacks and use the resulting position if something is returned if ( !noPropagation ) { var ui = this._uiHash(); if ( this._trigger( "drag", event, ui ) === false ) { this._mouseUp( new $.Event( "mouseup", event ) ); return false; } this.position = ui.position; } ※→this.helper[ 0 ].style.left = this.position.left + "px"; ※→this.helper[ 0 ].style.top = this.position.top + "px"; if ( $.ui.ddmanager ) { $.ui.ddmanager.drag( this, event ); } return false; }, 请查看倒数9,8行,我使用了“ ※→ ”作为标注,原文并没有这两个符号,我们需要将其修改为: this.helper[ 0 ].style.left = this.position.left / return_scale() + "px"; this.helper[ 0 ].style.top = this.position.top / return_scale() + "px"; 其中,return_scale()便是您的返回当前scale值的函数,请让left与top值除以这个scale,随后您的draggable便能够在scale下正确移动元素了! 以下为原本的答案,我没有删除它们,因为它们也能够完成同样的功能,如果您有需要的话,可以参看: *** 这是由于jquery-ui的draggable组件不会正确识别到scale带来的比例性变化,通过代码可以人工调整其出现的位置和移动的举例,以下为代码内容: //一个作为全局变量的初值,用于存储当前鼠标的位置 var click = { x:0, y:0}; $("可拖拽对象").draggable({ start: function(event) { //将event事件,即当我们开始拖动“可拖拽对象”时进行的点击事件时,鼠标的位置记录下来 click.x = event.clientX; click.y = event.clientY; }, //进入拖动阶段,此时的event是每一个拖动的瞬间,所进行的位移事件,而ui则是“可拖拽对象” //(关于ui的详细定义请参考jquery官方文档) drag: function(event, ui) { //通过任意手段得到父元素的scale的具体的值,此处我将这个值保存进了父元素的“scale”属性中 var 父元素_scale = $(父元素).attr("scale"); //这是ui对象在拖动事件开始时的位置,在此处我们将其用作位移的初始量,在scale变化后,这个值不会随之改变,这也是在拖动行为的一瞬间,出现“瞬移”情况的原因 var original = ui.originalPosition; //此时,我们对ui,也就是这个可拖拽对象的位置进行修改,由于通过originalPosition得到的位置是一个Position,即“相对于父元素的位置”,所以此处我们在修改ui的位置时,也要使用position()进行定位,而不是offset() ui.position = { //此处的值包括:位移起始点,拖动事件的鼠标位置,之前记录拖动开始时的鼠标,详细解释此处难以放置,请见下方详解 left: (original.left + event.clientX - click.x) / 父元素_scale, top: (event.clientY - click.y + original.top ) / 父元素_scale }; } }) ui position变化的详解,以下使用ui来代指可拖动对象,请注意区分 1.首先,我们可以得知,original所代表的是拖动开始之前,ui所在的位置,我们将这里设置为位移变化的起始点 2.此处的event.clinetX/Y代表的是drag事件中,鼠标移动后的位置,因此,(event.cliketX -click.x)就表示了从拖拽开始start,到drag的过程中,鼠标在x轴上移动的距离。我们希望ui持续跟随鼠标移动,那么我们就令ui在位置起始点的基础上,在x轴和y轴(也就是left和top)上对应地增加鼠标移动的距离,这样就能使得ui对象的“移动速度”和鼠标的“移动速度”打成一致了 3.最后,我们将得到的这个位置 / 父元素_scale,这包含了两方面的作用,首先,我们要知道的是,在scale后的元素上,鼠标的移动不会收到比例地影响,但是元素的位置变化却会收到scale的等比例影响,例如在scale = 0.5的父元素中向→移动100px,这会在视觉上表现为 想→移动了50px。而" / 父元素_scale"则能够将这种比例地变化调整回来,使得我们的鼠标向→拖拽了100px,对应的ui对象也向→移动了100px,最终便达成了我们需要的,在父元素经过scale处理后的元素上,仍然能够正常地移动 综上所述,这是我在实际的代码编辑中遇到的问题和解决的办法,这可能不是最好的或者效率最高的,但我认为,这仍然可以帮到一些人实现他们的功能。如果我的代码对任何人有帮助或者参考价值,我感到十分荣幸! 另外,在此处附上完整的,不带备注的代码,希望这能便于您使用: $(您的拖拽元素).draggable({ start: function(event) { click.x = event.clientX; click.y = event.clientY; }, drag: function(event, ui) { var 您的父元素的scale = return_scale(); var original = ui.originalPosition; ui.position = { left: (event.clientX - click.x + original.left) / 您的父元素的scale, top: (event.clientY - click.y + original.top ) / 您的父元素的scale }; } })