HTML5 使用 Hammer.js 拖动事件在 div 上拖放元素

Posted

技术标签:

【中文标题】HTML5 使用 Hammer.js 拖动事件在 div 上拖放元素【英文标题】:HTML5 drag and drop element over div with Hammer.js drag events 【发布时间】:2014-08-11 19:01:34 【问题描述】:

TL;DR

我想使用 html5 将元素拖放到带有拖动 Hammer.js 事件的容器中。但是,也有冲突。

详细说明:

如附图所示,我有两个容器:

    左: 带有可拖动元素的容器 右:包含 Hammer.js 事件的容器,即 drag、dragstart 和 dragend。

我想将元素从左侧容器拖放到右侧。 但是,在拖动时,当进入右侧容器时,会激活 Hammer.js 的 dragstart 事件。删除元素后,我在右侧容器上应用拖动事件。但是,Hammer.js 拖动事件被激活,它会考虑上一个 dragstart 事件中的 deltaX 和 deltaY。

Hammer.js 与 preventDefault: true: 一起使用:

Hammer(this.container, preventDefault: true).on('dragstart', function (event)  ... 

我已经在可拖动元素的dragstart上使用了event.preventDefault()和event.stopPropagation(),没有成功。

我也部分解决了这个问题。在 Hammer.js 容器的 dragstart 事件中,我添加了以下验证,以检查源元素和目标是否相同。但是,右侧容器中的拖动仅适用于第二个动作,因为第一个动作被忽略了。

if (event.gesture.startEvent.srcEvent.srcElement != event.gesture.target) 
     return false;

知道如何在使用 HTML5 拖放 API 拖动元素时防止 Hammer.js 事件吗?

我想使用标志作为最后的手段,因为 Hammer.js 事件应该由第三方开发。

感谢您的帮助。

【问题讨论】:

您已经找到解决方案了吗? 【参考方案1】:

Hammer.js 事件只有在它们之前被绑定时才应该被捕获。

尝试使用 case 语句...(这是来自我最近构建的一个应用程序)我可以 case 语句然后中断或返回 false 等以防止事情发生。但从理论上讲,如果我取消绑定或排除“拖动”事件,它应该仍然可以工作。

<script>
var hammertime = Hammer(document.getElementById('image-wrapper'), 
        transform_always_block: true,
        transform_min_scale: window.initScale,
        transform_max_scale: 1,
        drag_block_horizontal: true,
        drag_block_vertical: true,
        drag_min_distance: 0
    );

    //console.log(hammertime);

    var posX = window.calcLeft, posY = window.calcTop,
        lastPosX = window.calcLeft, lastPosY = window.calcTop,
        bufferX = 0, bufferY = 0,
        scale = window.initScale, last_scale,
        rotation = window.rotationNeeded, last_rotation, dragReady = 0;


 hammertime.on('touch drag dragend transform release mouseleave transformend pinchin pinchout', function (ev) 
        elemRect = document.getElementById('the-image');
        manageMultitouch(ev);
    );
function manageMultitouch(ev) 
        var pinchDirection;
        ev.stopPropagation();

        //console.log(ev.type);

        switch (ev.type) 
            case 'touch':
                last_scale = scale;
                last_rotation = rotation;

                break;

            case 'drag':

                posX = ev.gesture.deltaX + lastPosX;
                posY = ev.gesture.deltaY + lastPosY;

                break;

            case 'pinchin':

                console.log('pinchin');
                pinchDirection = "in";

                break;

            case 'pinchout':


                console.log('pinchout');
                pinchDirection = "out";


                break;

            case 'transform':

                rotation = window.rotationNeeded;// rotation + ev.gesture.rotation;//we can change this to snap rotation eventually.
                //console.log('Last Scale: ', last_scale);
                scale = Math.max(hammertime.options.transform_min_scale, Math.min(last_scale * ev.gesture.scale, 1));
                var propsImage = document.getElementById('the-image').getBoundingClientRect();
                //console.log(propsImage);
                var propsBox = document.getElementById('image-wrapper').getBoundingClientRect();
                //console.log(propsBox);


                break;

            case 'transformend':
                console.log('We are finished transforming.');
                //when they finish transforming, we need to determinw what the new left reset position would be.
                var propsImage = document.getElementById('the-image').getBoundingClientRect();
                var propsBox = document.getElementById('image-wrapper').getBoundingClientRect();
                //window.calcLeft = Math.round(window.preBounds.left - propsImage.left);
                //console.log(ev.type);
                //if (pinchDirection = "out") 

                window.calcLeft = Math.round(window.calcLeft + ((propsImage.width - propsBox.width) / 2));

                // else if (pinchDirection = "in") 

                //window.calcLeft = Math.round(window.calcLeft - ((propsImage.width - propsBox.width) / 2));
                //
                //window.calcTop = Math.round(window.calcTop + ((propsImage.top - propsBox.top) / 2));
                //console.log(window.calcLeft);


                break;

            case 'dragend':
                //console.log('We are finished dragging.');
                //console.log(window.calcLeft);
                lastPosX = posX;
                lastPosY = posY;
                checkBounds();


                break;

            case 'mouseleave':
                //console.log('Release!', posX, posY);
                //checkBounds();
                break;

        

<script>

【讨论】:

以上是关于HTML5 使用 Hammer.js 拖动事件在 div 上拖放元素的主要内容,如果未能解决你的问题,请参考以下文章

Hammer.js 中文教程(有 demo)

hammer.js学习

使用hammer.js 的Y-pan 事件延迟

使用 Hammer.js 时移动 Safari 崩溃

Hammer.js分析——input.js

移动端手势事件 hammer.JS插件