如何使一个jQuery UI中的“draggable()”div可以在触摸屏上拖动?

117

我有一个在Firefox和Chrome中工作的jQuery UI draggable()。用户界面的概念基本上是点击创建一个“便签”类型的项。

基本上,我点击或点击监听点击事件的 div#everything(100%高和宽),会显示一个输入文本区域。您添加文本,完成后保存。您可以拖动此元素。这在正常浏览器上有效,但在我可以测试的iPad上无法拖动项目。如果我轻触以选择(然后略微变暗),则无法拖动它。它根本不会向左或向右移动。我可以向上或向下拖动,但我不是拖动单个div,而是拖动整个网页。

因此,这是我用来捕获点击的代码:

$('#everything').bind('click', function(e){
    var elem = document.createElement('DIV');
    STATE.top = e.pageY;
    STATE.left = e.pageX;
    var e = $(elem).css({
        top: STATE.top,
        left: STATE.left
    }).html('<textarea></textarea>')
    .addClass('instance')
    .bind('click', function(event){
        return false;
    });
    $(this).append(e);
});

这里是我用来“保存”笔记并将输入 div 变成显示 div 的代码:

$('textarea').live('mouseleave', function(){
    var val = jQuery.trim($(this).val());
    STATE.content = val;
    if (val == '') {
        $(this).parent().remove();
    } else {
        var div  = $(this).parent();
        div.text(val).css({
            height: '30px'
        });
        STATE.height = 30;
        if ( div.width() !== div[0].clientWidth || div.height () !== div[0].clientHeight ) {
            while (div.width() !== div[0].clientWidth || div.height () !== div[0].clientHeight) {
                var h = div.height() + 10;
                STATE.height = h;
                div.css({
                    height: (h) + 'px'
                });     // element just got scrollbars
            }
        }
        STATE.guid = uniqueID()
        div.addClass('savedNote').attr('id', STATE.guid).draggable({
            stop: function() {
                var offset = $(this).offset();
                STATE.guid = $(this).attr('id');
                STATE.top = offset.top;
                STATE.left = offset.left;
                STATE.content = $(this).text();
                STATE.height = $(this).height();
                STATE.save();
            }
        });
        STATE.save();
        $(this).remove();
    }
});

当我加载用于保存笔记的页面时,我有这段代码:

$('.savedNote').draggable({
    stop: function() {
        STATE.guid = $(this).attr('id');
        var offset = $(this).offset();
        STATE.top = offset.top;
        STATE.left = offset.left;
        STATE.content = $(this).text();
        STATE.height = $(this).height();
        STATE.save();
    }
});

我的STATE对象负责保存笔记。

加载时,这是整个HTML主体:

<body> 
    <div id="everything"></div> 
<div class="instance savedNote" id="iddd1b0969-c634-8876-75a9-b274ff87186b" style="top:134px;left:715px;height:30px;">Whatever dude</div> 
<div class="instance savedNote" id="id8a129f06-7d0c-3cb3-9212-0f38a8445700" style="top:131px;left:347px;height:30px;">Appointment 11:45am</div> 
<div class="instance savedNote" id="ide92e3d13-afe8-79d7-bc03-818d4c7a471f" style="top:144px;left:65px;height:80px;">What do you think of a board where you can add writing as much as possible?</div> 
<div class="instance savedNote" id="idef7fe420-4c19-cfec-36b6-272f1e9b5df5" style="top:301px;left:534px;height:30px;">This was submitted</div> 
<div class="instance savedNote" id="id93b3b56f-5e23-1bd1-ddc1-9be41f1efb44" style="top:390px;left:217px;height:30px;">Hello world from iPad.</div> 

</body>
那么,我的问题是:如何在iPad上更好地使它工作?
我并不固执于使用jQuery UI,我想知道我是否在使用jQuery UI或jQuery方面做错了什么,或者是否有更好的框架来实现可拖动元素的跨平台/向后兼容性,以适用于触摸屏UI。
关于如何编写此类UI组件的更一般性意见也会受到欢迎。
谢谢!
更新: 我能够简单地将这个代码添加到我的jQuery UI draggable()调用中,并且在iPad上获得正确的可拖动性!
.touch({
    animate: false,
    sticky: false,
    dragx: true,
    dragy: true,
    rotate: false,
    resort: true,
    scale: false
});

jQuery Touch插件解决了这个问题!


1
我很好奇:您能用两到三个手指拖动 div 吗?我知道在移动版 Safari 中有时需要使用多个手指来滚动嵌入的内容,因此对于“可拖动”的内容也可能是一样的。 - Walter Mundt
沃尔特·曼特感谢您! 我还没有尝试过任何手指的变化,当我拿到它时,我会尝试一下! - artlung
1
两三个手指可以有效地防止“整个页面”被误滚,但对可拖动性没有影响。 - artlung
很遗憾,这种技术对我似乎没有起作用。 :( - blaster
@blaster 你需要查看其他答案以获取其他可能的解决方案。 - artlung
这个插件对我来说完美运作(可拖拽和可调整大小):https://github.com/furf/jquery-ui-touch-punch。演示在这里http://furf.com/exp/touch-punch/。该代码同时适用于常规浏览器和Android(未经iOS测试)。 - Calvin
7个回答

145

在浪费了很多时间后,我找到了这个!

jquery-ui-touch-punch

它将触摸事件转换为点击事件。 记得在jQuery之后加载该脚本。

我在iPad和iPhone上让它工作了。

$('#movable').draggable({containment: "parent"});

2
这个解决方案非常好,我尝试过的另一个答案有缺陷,真的没有帮助。 - musefan
一个小提示:它非常有效,尽管如果可拖动元素被像带有蒙版的图像这样的层覆盖,则不会激活拖动,但解决方案是在顶部层上添加pointer-events:none;。 - Adler
这是一个非常好且简单的解决方案,你只需要使用插件并继续使用 JQuery 可拖动函数即可。太棒了,谢谢! - almost a beginner
这将防止可拖动区域内的可点击项。 - Abdul Sadik Yalcin

62

注意: 这篇答案是在2010年写的,技术发展很快。如果需要更新的解决方案,请查看下面@ctrl-alt-dileep的回答


根据您的需求,您可能希望尝试使用jQuery触摸插件;您可以在此处尝试一个示例。它可以在我的iPhone上正常拖动,而jQuery UI Draggable则无法实现。

或者,您可以尝试这个插件,不过这可能需要您编写自己的可拖动函数。

顺便说一下:信不信由你,我们听到了越来越多的关于iPad和iPhone等触摸设备如何对使用:hover/onmouseover功能和可拖动内容的网站造成问题的传闻。

如果您对其底层解决方案感兴趣,可以使用三个新的JavaScript事件:ontouchstart、ontouchmove和ontouchend。苹果实际上已经撰写了一篇关于它们的文章,您可以在这里找到。一个简化的示例可以在这里找到,这些事件都在我链接的两个插件中使用。


2
太棒了!我所要做的就是在我的现有draggable()调用上链接.touch({ animate: false, sticky: false, dragx: true, dragy: true, rotate: false, resort: true, scale: false });,它完美地工作了!我仍然需要解决所有我想处理的事件,以获得正确的工作流程,但jQuery触摸插件解决了问题! - artlung
5
这个插件似乎在jquery.com上已不再提供。你仍然可以在这里找到对应的JavaScript文件:http://www.manifestinteractive.com/iphone/touch/js/jquery.touch.js - bjelli
1
嘿,现在manifestinteractive.com上插件也不见了。试试这个:http://plugins.jquery.com/files/jquery.touch.js.txt - Ian Hunter
6
此答案已不再适用。请查看@ctrl-alt-dileep的回答(jquery-ui-touch-punch),该回答提供了2012年的解决方案。 - bjelli
1
@bjelli 谢谢您指出这个问题。我已经更新了我的答案并加上了一个警告。 :) - vonconrad
显示剩余3条评论

24

7

3
这很棒,他们正在处理1.9版本的问题。值得一提的是,我发现演示中的代码版本存在错误,效果不太好。有人在这个问题的链接中发布了一个更正确的版本,对我来说效果更好:https://dev59.com/5Gw15IYBdhLWcg3wO5OX - asgeo1
我更新了我的答案来解决这个问题。在我的使用情况中,原始版本没有出现任何错误。 - pizza247

4

2
你可以尝试使用 jquery.pep.js

jquery.pep.js 是一个轻量级的 jQuery 插件,可以将任何 DOM 元素变成可拖动的对象。它适用于几乎所有浏览器,从旧到新,从触摸到点击都可以。我创建它是为了满足一个需求,因为 jQuery UI 的可拖动功能在触摸设备上无法正常工作(需要一些技巧)。

网站GitHub 链接


1
谢谢@martynas,我会去看看! - artlung

2
昨天我遇到了类似的问题。我已经使用jQuery UI的draggable和jQuery Touch Punch来解决这个问题,这些方法在其他答案中也有提到。然而,对于某些安卓设备,使用这种方法会导致奇怪的错误,因此我决定编写一个小型的jQuery插件,通过使用触摸事件而不是模拟鼠标事件的方法,使HTML元素可拖动。
结果是 jQuery Draggable Touch,它是一个简单的jQuery插件,用于使元素可拖动,主要针对触摸设备使用触摸事件(如touchstart、touchmove、touchend等)。如果浏览器/设备不支持触摸事件,则仍有一个回退选项使用鼠标事件。

嗨Heyman,做得很好。感谢您的分享。 这个也适用于jQuery resizable吗? - Haris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接