当jQuery-ui可拖动在移动浏览器上失败时,拖放!(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/drag-and-drop-when-jquery-ui-draggable-fails-on-mo-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 7 分钟阅读 - 3022 个词 阅读量 0当jQuery-ui可拖动在移动浏览器上失败时,拖放!(译文)
原文地址:https://www.codeproject.com/Articles/1147610/Drag-and-Drop-when-jQuery-ui-draggable-Fails-on-Mo
原文作者:luigidibiasi
译文由本站 robot-v1.0 翻译
前言
This article describes yet another drag and drop approach that can be used when the jQuery-ui and touch-punch library fails (when the project uses transform-origin or other coordinate transformations)
本文介绍了另一种拖放方法,当jQuery-ui和touch-punch库失败时(当项目使用transform-origin或其他坐标转换时)可以使用该方法
介绍(Introduction)
这是我在CodeProject上的第四篇文章,希望您能体会到它,因为在以下各段中,我想描述和处理一个在Web开发人员的生命中只会出现几次的缺陷!(This is my fourth article on CodeProject and I hope that you will can appreciate it because in the following paragraphs, I would like to describe and handle a drawback that only appears a few times in the life of a web developer!)
jQuery,jQuery-ui和触摸袋库可以被视为桌面和移动浏览器中拖放操作的标准事实.这是因为这三个库仅通过调用一种方法就可以忽略拖放操作的所有复杂性:(jQuery, jQuery-ui and touch-pouch library can be considered the standard de facto for drag and drop operations in desktop and mobile browser. This because these three libraries permit ignoring all the complexity of a drag and drop operation, just by calling one method:) $.draggable()
通知jQuery子系统可以拖动对象.(that informs the jQuery subsystem that an object can be dragged.)
的(The) $.draggable
方法可以用(method can be decorated with) drop: function (event,ui) {}
参数,我们可以在其中添加用于处理drop事件的代码.(parameter in which we can add the code for handling the drop event.)
这看起来很完美!但是,当我们使用一些新的CSS3功能时会发生什么?(This seems perfect! But, what happens when we use some new CSS3 features?)
背景(Background)
在高响应环境中工作时,我们可以使用(When we are working in high responsive environment, we could use)转变(transformations)喜欢(like) transform-coordinate
,(,) transform:scale()
,(,) transform:rotate
等等.看来jQuery(and so forth. It seems that jQuery)不喜欢(does not like)这种情况非常严重,在某些情况下,(this occurrence very much and, in some cases,)在某些动作中可能会犯错(it can make a mistake in some actions).(.)
对于本文,我选择了(For this article, I have chosen) HYPE3(HYPE3) 和(and) 肿瘤(TUMULT) 允许以自动方式处理缩放和调整大小.为了显示错误,我准备了两个示例.(that permits the handling re-scaling and re-sizing in an automatic way. I prepared two examples in order to show the mistakes.)
在以下图片中,您可以通过以下方式查看在不同设备上调整大小和缩放比例的相同对象:(In the following pictures, you can view the same objects resized and rescaled on different devices by) HYPE
没有任何用户代码的引擎.(engine without any user codes.)
桌面浏览器视图(Desktop Browser View)
Iphone横向和纵向视图(Iphone Landscape and Portrait Views)
如您所见,所有三个视图似乎都相同(按视口大小重新缩放).(As you can see, all three views seem to be the same (rescaled referred to viewport size).) 但是,我想邀请你一起玩(But, I would like to invite you to play) 演示1(demo1) 在不同的浏览器上.您可以尝试进行拖放操作,因为(on different browsers. You can experiment that the drag and drop will fail because)拖动还原将错误的返回坐标(drag revert will mistake the return coordinates)在横向和桌面浏览器中使用(不尊重原始位置).(in landscape and desktop browser (the original position will not be respected).) 我不确定这种问题是否会再次发生,但是我可以确认使用坐标变换功能时会出现此问题.(I am not sure about the recurrence of this kind of problem, but I can confirm that this issue appears when the coordinate transformation function is used.)请注意,DEMO1仅使用jQuery,jQuery-ui和touch-pouch库,而不使用本机拖放功能.(Note that DEMO1 only uses jQuery, jQuery-ui and touch-pouch libraries and not the native drag and drop support.)
使用代码(Using the Code)
我认为可拖动的还原问题将落在jQuery-ui实现中,但我对此不确定.因此,我的想法是废弃jQuery-ui和pouch-touch库并使用:(I think that the draggable revert issues will lie in jQuery-ui implementation but I’m not sure about this. So, my idea was to trash jQuery-ui and pouch-touch libraries and to use:)
- 本地桌面浏览器拖放(Chrome,Firefox,Opera,Safari和Edge支持它)(Native Desktop browser drag and drop (Chrome, Firefox, Opera, Safari and Edge support it))
- 用于移动浏览器拖放功能的触摸事件(Touch-events for mobile browser drag and drop capability)
桌面浏览器本机支持(Desktop Browser Native Support)
这种方法的第一步必须是为要使其可拖动的每个对象分配一个类或唯一ID.在我的示例中,所有彩色正方形均命名为(The first step for this kind of approach must be the assignment of a class or unique-id to each object which we want to made draggable. In my example, all colored squares were named) c1
,(,) c2
…(…) c12
并具有类名(and have the class name) gameObject
.因此,我仅使用以下代码启用本机拖动功能.(. So, I just enable the native drag function with following code.)
for (var c=1;c<=12;c++)
{
var e = document.getElementById("c"+c);
$("#c"+c).attr("draggable","true");
$("#c"+c).attr("ondragstart","_dragStart(event)");
$("#c"+c).attr("ondrop","_onDrop(event)");
$("#c"+c).attr("ondragover","_onDragOver(event)");
}
为了简单起见,我已经报告了在分离的代码块中处理拖放的三个函数(For simplicity, I have reported the three functions that handle drag and drop in separated code blocks)
function _dragStart(a)
{
a.dataTransfer.setData("text", a.target.id);
}
function _onDrop(e)
{
e.preventDefault();
var src = e.dataTransfer.getData("text");
var dst = e.target.id;
// here you can do what you want with source and destination of drag and drop !
}
function _onDragOver(a)
{
a.preventDefault();
}
移动浏览器拖放操作(Mobile Browser Drag and Drop with Touches)
如今,移动浏览器尚未实现对拖放的本地支持.因此,第二步是处理代表可触摸屏幕上的拖放动作的三个手势:(Nowadays, mobile browsers do not implement a native support for drag and drop. So, the second step was to handle the three gestures that represents a drag and drop action on a touchable screen:) touchstart
,(,) touchmove
和(and) touchend
.(.)
所有拖放操作都使用有助于操作的阴影(又称"鬼影")图像.该图像将显示在光标附近,以向用户显示哪些对象正在移动.我们还需要跟踪对象的开始位置,以恢复拖放操作.(All drag and drop operations use a shadow (aka ghost) image that helps the actions. This image will be shown near the cursor in order to show the user which objects are moving. We also need to track the start position of an object in order to revert drag and drop.)
以下三个变量可以帮助我们进行操作!你可以试试(The following three variables can help us with touches! You can try) 演示2(DEMO2) 为了尝试这种方法.(in order to try this kind of approach.)
// touch capability
var startPos=[];
var toDrag = null;
var dragStart = false;
然后,对于每个(Then, for each)触摸屏幕(touch on screen),我们需要了解用户是否点击了可拖动对象.这可以通过简单的冲突检测来完成.(, we need to understand if the user hits a draggable object. This can be done by simple collision detection.)
$(document).on("touchstart",function(e) {
e.preventDefault();
// touch coordinates
var xPos = e.originalEvent.touches[0].pageX;
var yPos = e.originalEvent.touches[0].pageY;
startPos[0]=xPos;
startPos[1]=yPos;
$(".gameobject").each(function(index)
{
var jx = parseFloat($(this).offset().left);
var jy = parseFloat($(this).offset().top);
var jw = parseFloat($(this).width());
var jh = parseFloat($(this).height());
//collision detect
if (jx <= xPos && jy <= yPos && xPos <= (jx+jw) && yPos <= (jy+jh))
{
if ($(this).attr("draggable")=="false")
{
//object touched is not draggable!
}
else {
// collision detected
toDrag = $(this).attr("id");
dragStart=true;
// setting up shadow image
var shadow = document.getElementById("shadow");
if (shadow==null)
{
shadow = document.createElement("div");
document.getElementById("game").appendChild(shadow);
shadow.setAttribute("id","shadow");
shadow.style.position="absolute";
shadow.style.zIndex="9999999";
}
// for the purpose of this article ghost image will be a square of
// the same color of touched object
$("#shadow").css("visibility","visible");
var shadowImg = $(this).css("background-image");
$("#shadow").css("background-image",shadowImg);
$("#shadow").css("background-size","100% 100%");
$("#shadow").css("left",xPos+"px");
$("#shadow").css("top",yPos+"px");
$("#shadow").css("width",jw+"px");
$("#shadow").css("height",jh+"px");
return;
}
}
});
});
现在,我们检测到可拖动对象发生碰撞,因此我们需要通过跟随其他任何触摸来跟踪用户的手指.这可以用几行代码来完成.(Now, we detected a collision on draggable object and therefore we need to track the finger of the user by following any other touches. This can be done with a few lines of code.)
$(document).on("touchmove",function(e) {
e.preventDefault();
if (dragStart && toDrag!=null)
{
// move the shadow
var xPos = e.originalEvent.touches[0].pageX;
var yPos = e.originalEvent.touches[0].pageY;
var sw = parseFloat($("#shadow").width());
var sh = parseFloat($("#shadow").height());
$("#shadow").css("left",(xPos-sw/2)+"px");
$("#shadow").css("top",(yPos-sh/2)+"px");
}
});
最后,我们需要了解手指离开屏幕的位置.这将是我们阴影图像的最后一个坐标,因此(Finally, we need to understand where the finger leaves the screen. This will be the last coordinates of our shadow images and so the)下降位置(drop position).(.)
$(document).on("touchend",function(e) {
e.preventDefault();
if (dragStart && toDrag!=null)
{
//here you can apply graphics effect on shadow like revert to initial pos or fade out
$("#shadow").css("visibility","hidden");
dragStart=false;
var xPos = 0;
var yPos = 0;
if (e.changedTouched==undefined)
{
xPos = e.originalEvent.changedTouches[0].pageX;
yPos = e.originalEvent.changedTouches[0].pageY;
}
else
{
xPos = e.changedTouches[0].pageX;
yPos = e.changedTouched[0].pageY;
}
// looking for collision between gameObject and touchleave position
var target = null;
$(".gameobject").each(function(index) {
var tx = parseFloat($(this).offset().left);
var ty = parseFloat($(this).offset().top);
var tw = parseFloat($(this).width());
var th = parseFloat($(this).height());
if (tx <= xPos && ty <= yPos && xPos <= (tx+tw) && yPos <= (ty+th))
{
target = $(this).attr("id");
//here you can execute code on source and target
return;
}
}).promise().done(function() { });
}
});
}
兴趣点(Points of Interest)
如果有人知道解决此问题的jQuery-ui配置参数,那么本文可能就没有用.我不知道任何方法,但是我不确定是否存在.(This article could be useless if anyone knows a jQuery-ui configuration parameter that fixes this problem. I don’t know any method, but I’m not sure whether one exists.)
历史(History)
- 提高英语水平(向Natascia Spada致敬)@ 27/10/2016-12:18(Improving English (Thx to Natascia Spada) @ 27/10/2016 - 12:18)
- 发表于25/10/2016-15:00(Published @ 25/10/2016 - 15:00)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
jQuery-UI jQuery touchscreen touch 新闻 翻译