在缩放的div上拖动元素

时间:2015-03-03 00:21:49

标签: javascript jquery jquery-ui jquery-ui-draggable

我尝试使用jquery内置的draggable,我尝试使用自定义拖动功能但无济于事。两者都有他们尊重的问题,我会尽力突出他们。

基本上,我试图允许拖动一个缩放的div容器上的元素。以下方法在小于2的缩放元素上运行 okay 。但如果你高于此值,我们会看到一些问题。

任何帮助将不胜感激。谢谢你的时间。

HTML

<div id="container">
    <div id="dragme">Hi</div>
</div>

方法1(Jquery可拖动函数)

我已尝试过jquery draggable函数,您可以在此jsfiddle示例中看到。

我在这个例子中发现的问题如下:

  • 最大问题:可放大容器在放大时不会更改。因此,如果元素被拖过部分缩放容器而不是原始尺寸的一部分,则会失败。
  • 当您点击拖动div时,它会远离鼠标传送一点点,而不是无缝拖动。

JS

var percent = 2.5;

$("#dragme").draggable({
    zIndex: 3000,
    appendTo: 'body',
    helper: function (e, ui) {
        var draggable_element = $(this),
            width = draggable_element.css('width'),
            height = draggable_element.css('height'),
            text = draggable_element.text(),
            fontsize = draggable_element.css('font-size'),
            textalign = draggable_element.css('font-size');
        return $('<div id="' + draggable_element.id + '" name="' + draggable_element.attr('name') + '" class="text">' + text + '</div>').css({
            'position': 'absolute',
                'text-align': textalign,
                'background-color': "red",
                'font-size': fontsize,
                'line-height': height,
                'width': width,
                'height': height,
                'transform': 'scale(' + percent + ')',
                '-moz-transform': 'scale(' + percent + ')',
                '-webkit-transform': 'scale(' + percent + ')',
                '-ms-transform': 'scale(' + percent + ')'
        });
    },
    start: function (e, ui) {
        $(this).hide();
    },
    stop: function (e, ui) {
        $(this).show();
    }
});

$("#container").droppable({
    drop: function (event, ui) {
        var formBg = $(this),
            x = ui.offset.left,
            y = ui.offset.top,
            drag_type = ui.draggable.attr('id');

        var element_top = (y - formBg.offset().top - $(ui.draggable).height() * (percent - 1) / 2) / percent,
            element_left = (x - formBg.offset().left - $(ui.draggable).width() * (percent - 1) / 2) / percent;

        $(ui.draggable).css({
            'top': element_top,
                'left': element_left
        });

    }
});

方法2 - 自定义拖动功能

我尝试过使用自定义拖动功能,但在2比例后它无法使用。

  • jsfiddle scale(2) - 看起来可拖动的div正在癫痫发作。
  • jsfiddlescale(2.5)上 - 当您尝试拖动时,可拖动的div会飞走。

JS

(function ($) {
    $.fn.drags = function (opt) {

        opt = $.extend({
            handle: "",
            cursor: "move"
        }, opt);

        if (opt.handle === "") {
            var $el = this;
        } else {
            var $parent = this;
            var $el = this.find(opt.handle);
        }

        return $el.css('cursor', opt.cursor).on("mousedown", function (e) {
            if (opt.handle === "") {
                var $drag = $(this).addClass('draggable');
            } else {
                $(this).addClass('active-handle')
                var $drag = $parent.addClass('draggable');
            }

            var
            drg_h = $drag.outerHeight(),
                drg_w = $drag.outerWidth(),
                pos_y = $drag.offset().top + drg_h - e.pageY,
                pos_x = $drag.offset().left + drg_w - e.pageX;

            follow = function (e) {
                $drag.offset({
                    top: e.pageY + pos_y - drg_h,
                    left: e.pageX + pos_x - drg_w
                })
            };

            $(window).on("mousemove", follow).on("mouseup", function () {
                $drag.removeClass('draggable');
                $(window).off("mousemove", follow);
            });

            e.preventDefault(); // disable selection

        }).on("mouseup", function () {
            if (opt.handle === "") {
                $(this).removeClass('draggable');
            } else {
                $(this).removeClass('active-handle');
                $parent.removeClass('draggable');
            }
        });

    }
})(jQuery);

$("#dragme").drags({}, function (e) {});

3 个答案:

答案 0 :(得分:4)

以下是我的一些调查结果,以确保拖动缩放容器适用于方法一。唯一需要注意的是,在发生任何这些操作之前,请确保将var percent作为已声明的缩放百分比。

首先,在javascript的顶部使用此代码。这将有助于确保可投放区域与带帽的容器一起工作。

$.ui.ddmanager.prepareOffsets = function( t, event ) { var i, j, m = $.ui.ddmanager.droppables[ t.options.scope ] || [], type = event ? event.type : null, list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); droppablesLoop: for ( i = 0; i < m.length; i++ ) { if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) { continue; } for ( j = 0; j < list.length; j++ ) { if ( list[ j ] === m[ i ].element[ 0 ] ) { m[ i ].proportions().height = 0; continue droppablesLoop; }  } m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; if ( !m[ i ].visible ) { continue; } if ( type === "mousedown" ) { m[ i ]._activate.call( m[ i ], event ); } m[ i ].offset = m[ i ].element.offset(); m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth * percent, height: m[ i ].element[ 0 ].offsetHeight * percent }); } };

以下是修复拖动所需的一些功能,因此它可以在缩放容器上运行。

function dragFix(event, ui) { var changeLeft = ui.position.left - ui.originalPosition.left, newLeft = ui.originalPosition.left + changeLeft / percent, changeTop = ui.position.top - ui.originalPosition.top, newTop = ui.originalPosition.top + changeTop / percent; ui.position.left = newLeft; ui.position.top = newTop; }

function startFix(event, ui) { ui.position.left = 0; ui.position.top = 0;  var element = $(this); }

如果要在已缩放的容器上启用元素可以调整大小,则需要这样做。

function resizeFix(event, ui) { var changeWidth = ui.size.width - ui.originalSize.width, newWidth = ui.originalSize.width + changeWidth / percent, changeHeight = ui.size.height - ui.originalSize.height, newHeight = ui.originalSize.height + changeHeight / percent;  ui.size.width = newWidth; ui.size.height = newHeight; }

要使元素可拖动,我使用以下函数。

$("ELEMENT").resizable({ minWidth: - ($(this).width()) * 10, minHeight: - ($(this).height()) * 10, resize: resizeFix, start: startFix });
$("ELEMENT").draggable({ cursor: "move", start: startFix, drag: dragFix }); }

答案 1 :(得分:1)

此处提到了类似的问题:jquery - css "transform:scale" affects '.offset()' of jquery

似乎问题是由于jQuery无法返回缩放元素的确切大小,因此无法为元素设置正确的偏移值。

为了解决这个问题,他建议首先将比例设置为1并设置偏移,然后再重置比例值。

但仅此一点并不能解决这里的问题。由于在缩放时采用鼠标位置,因此位置值也应除以比例值。

以下是代码的编辑版本:

  var scl = 2.5;
  var
    drg_h = $drag.outerHeight(),
    drg_w = $drag.outerWidth(),
    pos_y = $drag.offset().top/scl + drg_h - e.pageY/scl,
    pos_x = $drag.offset().left/scl + drg_w - e.pageX/scl;

  follow = function(e) {
    var size = {
      top:e.pageY/scl + pos_y - drg_h+scl*2,
      left:e.pageX/scl + pos_x - drg_w+scl*2
    };
      $drag.parent().css("transform","scale(1)");
      $drag.offset(size);
      $drag.parent().css("transform","scale("+scl+")");
  };

注意:我只更换了transform代码的比例值,因为我使用的是chrome。您也可以替换所有实例,或者您可以使用具有1个缩放值的其他类。

JSFiddle也是here

答案 2 :(得分:-1)

以下是使用缩放进行简单拖动的示例,但是,在prue dom中。

<style>
#dragme {
    position:absolute;
    border:1px solid red;
    background:pink;
    left:10px;
    top:20px;
    width:100px;
    height:200px;
}
#container {
    transform: scale(2,2) translate(100px,100px);
    position:relative;
    border:1px solid green;
    background:grey;
    width:200px;
    height:300px;
}
</style>
<body>

<div id="container">
    <div id="dragme">Hi</div>
</div>


    <script>
    var dragme=document.getElementById("dragme");
    var container=document.getElementById("container");
    dragme.onmousedown=function Drag(e){
        this.ini_X = this.offsetLeft-e.clientX/2;
        this.ini_Y = this.offsetTop-e.clientY/2;
        container.onmousemove = move;
        container.onmouseup = release;
      return false;
    }
    function move(e){
        e.target.style.left = e.clientX/2 + e.target.ini_X + 'px';
        e.target.style.top = e.clientY/2 + e.target.ini_Y + 'px';
    }
    function release(){
        container.onmousemove=container.onmouseup=null;
}

    </script>
    </body>