【问题标题】:Javascript Drag and drop for touch devices [closed]用于触摸设备的Javascript拖放[关闭]
【发布时间】:2011-07-08 08:54:17
【问题描述】:

我正在寻找适用于触控设备的拖放插件。

我想要与jQuery UI plugin 类似的功能,它允许“可放置”元素。

jqtouch plugin支持拖拽,不支持拖放。

Here 是拖放,只支持 iPhone/iPad。

谁能给我指出一个适用于 android/ios 的拖放插件的方向?

...或者可能更新 jqtouch 插件以获得可放置性,它已经在 Andriod 和 IOS 上运行。

谢谢!

【问题讨论】:

  • 这个正在进行中,但我不知道哪些设备支持它:这个plugins.jquery.com/project/mobiledraganddrop ...你浏览过 jQuerymobile.com 库吗?我还发现了这个重复的 SO 问题:stackoverflow.com/questions/3172100/…
  • 谢谢。是的,mobiledraganddrop 仅支持在移动设备上单击和放置。我在 jQuerymobile.com 上找不到任何东西。另一个问题的答案已被标记为正确,指的是具有有限源许可证的sencha.com/products/touch
  • 我很好奇可以在移动和桌面浏览器上运行的浏览器。

标签: javascript jquery jquery-ui touch


【解决方案1】:

您可以使用 Jquery UI 进行拖放,并使用附加库将鼠标事件转换为您需要的触摸,我推荐的库是 https://github.com/furf/jquery-ui-touch-punch,这样您从 Jquery UI 的拖放操作应该可以正常工作触摸设备

或者您可以使用我正在使用的这段代码,它还将鼠标事件转换为触摸,它就像魔术一样工作。

function touchHandler(event) {
    var touch = event.changedTouches[0];

    var simulatedEvent = document.createEvent("MouseEvent");
        simulatedEvent.initMouseEvent({
        touchstart: "mousedown",
        touchmove: "mousemove",
        touchend: "mouseup"
    }[event.type], true, true, window, 1,
        touch.screenX, touch.screenY,
        touch.clientX, touch.clientY, false,
        false, false, false, 0, null);

    touch.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init() {
    document.addEventListener("touchstart", touchHandler, true);
    document.addEventListener("touchmove", touchHandler, true);
    document.addEventListener("touchend", touchHandler, true);
    document.addEventListener("touchcancel", touchHandler, true);
}

然后在你的 document.ready 中调用 init() 函数

Here找到的代码

【讨论】:

  • 谢谢,我的 Android 设备上的东西现在可以拖动了。但是,当我单击它时,不再触发 click 事件。任何想法如何解决这个问题?
  • 注意:由于为整个文档注册了事件侦听器,因此此解决方案还会禁用我的 Nexus S 上的滚动...
  • 感谢分享。但是,您应该感谢您发布的代码的原始作者。 ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript
  • @JohnLandheer 我通过仅将事件侦听器附加到我想要可拖动的对象来解决问题,document.getElementById('draggableContainer').addEventListener(...
  • 触控打孔很棒。那些“它只是工作”的东西之一。唉,它不支持双点触控……我很乐意看到。
【解决方案2】:

感谢以上代码! - 我尝试了几个选项,这就是票。我遇到的问题是 preventDefault 阻止在 ipad 上滚动 - 我现在正在测试可拖动项目,到目前为止效果很好。

if (event.target.id == 'draggable_item' ) {
    event.preventDefault();
}

【讨论】:

  • 你在 Windows Phone 中测试过这个吗?还是 iPhone 以外的任何东西?从过去的经验来看,这似乎在 iPhone/iPad 上运行良好,但在其他设备上效果不佳,尤其是在 Windows Phone 上。
【解决方案3】:

我有与gregpress answer 相同的解决方案,但我的可拖动项目使用了一个类而不是一个ID。它似乎有效。

var $target = $(event.target);  
if( $target.hasClass('draggable') ) {  
    event.preventDefault();  
}

【讨论】:

  • 您只是使用了不同的选择器这一事实并不保证是一个单独的答案,而是您应该对@gregpress 的答案发表评论。
  • @bPratik 除非他希望答案提供更好的格式——而且他提供了一个完整的代码示例这一事实确实需要单独的答案。不过应该留下评论链接到他的答案......
【解决方案4】:

对于任何希望使用此功能并保留“点击”功能的人(正如 John Landheer 在他的评论中提到的那样),您只需进行几处修改即可:

添加几个全局变量:

var clickms = 100;
var lastTouchDown = -1;

然后把原来的switch语句修改成这样:

var d = new Date();
switch(event.type)
{
    case "touchstart": type = "mousedown"; lastTouchDown = d.getTime(); break;
    case "touchmove": type="mousemove"; lastTouchDown = -1; break;        
    case "touchend": if(lastTouchDown > -1 && (d.getTime() - lastTouchDown) < clickms){lastTouchDown = -1; type="click"; break;} type="mouseup"; break;
    default: return;
}

您可能想根据自己的喜好调整“点击次数”。基本上,它只是观察“touchstart”,然后是“touchend”,以模拟点击。

【讨论】:

  • @E. Z. Hart - 你能告诉我把你的代码放在上面给定的代码中以启用点击事件吗???
  • @ChakoDesai - 自从我写下我的回复以来,答案中的代码已经被大量编辑。查看 stackoverflow.com/posts/6362527/revisions 并查看 2011 年 6 月 30 日的代码;根据那个版本,我的回答会更有意义。
  • @E. Z. Hart - 我已经从给定的 url 更新了我的代码。但是为什么有时click 有效而有时无效???
  • @ChakoDesai - 没有看到你的代码我不能确定。您可能想为此提出一个新问题。
  • 可以在此处找到使上述代码适用于点击事件的更新答案:stackoverflow.com/questions/28218888/…
【解决方案5】:

我知道的旧线程......

@ryuutatsuo 的答案的问题是它还阻止了任何输入或其他必须对“点击”做出反应的元素(例如输入),所以我写了这个解决方案。该解决方案可以在任何触摸设备(或计算机)上使用基于 mousedown、mousemove 和 mouseup 事件的任何现有拖放库。这也是一种跨浏览器的解决方案。

我已经在多种设备上进行了测试,它运行速度很快(结合 ThreeDubMedia 的拖放功能(另请参阅 http://threedubmedia.com/code/event/drag))。它是一个 jQuery 解决方案,因此您只能将它与 jQuery 库一起使用。我使用了 jQuery 1.5.1,因为一些 较新的函数在 IE9 及更高版本中无法正常工作(未使用较新版本的 jQuery 进行测试)。

之前向事件添加任何拖放操作您必须先调用此函数

simulateTouchEvents(<object>);

您还可以使用以下语法阻止所有组件/子组件进行输入或加速事件处理:

simulateTouchEvents(<object>, true); // ignore events on childs

这是我写的代码。我使用了一些不错的技巧来加快评估速度(参见代码)。

function simulateTouchEvents(oo,bIgnoreChilds)
{
 if( !$(oo)[0] )
  { return false; }

 if( !window.__touchTypes )
 {
   window.__touchTypes  = {touchstart:'mousedown',touchmove:'mousemove',touchend:'mouseup'};
   window.__touchInputs = {INPUT:1,TEXTAREA:1,SELECT:1,OPTION:1,'input':1,'textarea':1,'select':1,'option':1};
 }

$(oo).bind('touchstart touchmove touchend', function(ev)
{
    var bSame = (ev.target == this);
    if( bIgnoreChilds && !bSame )
     { return; }

    var b = (!bSame && ev.target.__ajqmeclk), // Get if object is already tested or input type
        e = ev.originalEvent;
    if( b === true || !e.touches || e.touches.length > 1 || !window.__touchTypes[e.type]  )
     { return; } //allow multi-touch gestures to work

    var oEv = ( !bSame && typeof b != 'boolean')?$(ev.target).data('events'):false,
        b = (!bSame)?(ev.target.__ajqmeclk = oEv?(oEv['click'] || oEv['mousedown'] || oEv['mouseup'] || oEv['mousemove']):false ):false;

    if( b || window.__touchInputs[ev.target.tagName] )
     { return; } //allow default clicks to work (and on inputs)

    // https://developer.mozilla.org/en/DOM/event.initMouseEvent for API
    var touch = e.changedTouches[0], newEvent = document.createEvent("MouseEvent");
    newEvent.initMouseEvent(window.__touchTypes[e.type], true, true, window, 1,
            touch.screenX, touch.screenY,
            touch.clientX, touch.clientY, false,
            false, false, false, 0, null);

    touch.target.dispatchEvent(newEvent);
    e.preventDefault();
    ev.stopImmediatePropagation();
    ev.stopPropagation();
    ev.preventDefault();
});
 return true;
}; 

它的作用: 首先,它将单点触摸事件转换为鼠标事件。它检查事件是否由必须拖动的元素上/中的元素引起。如果它是一个输入元素,如 input、textarea 等,它会跳过翻译,或者如果附加了标准鼠标事件,它也会跳过翻译。

结果: 可拖动元素上的每个元素仍在工作。

快乐的编码,greetz, 欧文·汉杰斯

【讨论】:

  • 我应该传入哪个对象simulateTouchEvents(&lt;object&gt;, true);???
  • 例如:simulateTouchEvents( $('#yourid; ), true );或模拟TouchEvents(document.getElementById('yourid'), true);等
  • 你能看看我的另一个问题link???
  • 使用 threedubmedia.com/code/event/drag 并禁用元素的 x 或 y 移动。当您使用本文中的代码时,您可以“滚动”滚动条。但是要知道为什么要这样做,因为手机上的页面已经有了滚动条。不明白你想用它做什么。成功!
  • 我必须添加列的拖放和滚动。当我在chrome 中打开touch 事件时,我无法滚动表格。甚至在移动设备上也没有。
猜你喜欢
  • 2011-03-23
  • 2011-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多