3

1つの要素とイベントにバインドされた2つの異なる関数があります。基本的に、これらは「マウスダウン」で呼び出されます。

要素を「サイズ変更」または「移動/ドラッグ」できるようにする方法を見つけようとしていますが、両方を同時に行うことはできません。

現在、「resize」関数が呼び出されたときにクリアされる「setTimeout」関数を使用しています。これを行うことで、「move/drag」関数をキャンセルします。それは機能しますが、まったくうまくいきません。

より良い方法を見つけるのに助けが必要です。何か提案をいただければ幸いです。

var timer= "",
    resize_select = false;

$('element').resize(function() {
    resize_select = true;
    //do stuff, called every resize, just like resizing <textarea> 
    window.clearTimeout(timer);
});

$('element').on("mousedown", function() {
    $(this) = $this;
    resize_select = false;

    if (resize_select === false) {
        timer = setTimeout(function() {
            $this.addClass('dragable');
        }, 500);
    }

    $(document).on("mousemove", function(e) {
        $('.dragable').css({
            top: e.pageY,
            left: e.pageX
        });
    });
});

$(document).on('mouseup', function() {
    resize_select = false;
    $('.resize').removeClass('dragable');
});

私はBenAlmanの「jQueryresizeevent」を使用して、任意の要素を.resize()にバインドできるようにしています。

ここに私が現在いる場所のjsfiddleがあります


更新しました

$('.resize').css({
    resize:'both',
    overflow:'hidden'
});

$('.resize').on('mousedown', function(event) {
    var $this = $(this),
        $this_height = $this.height(),
        $this_width = $this.width(),
        x = event.pageX - $this.offset().left,
        y = event.pageY - $this.offset().top,
        xx = $this_width - 10,
        yy = $this_height - 10,
        img_num = $(this).index();

    event.preventDefault();

    if (xx - x > 0 || yy - y > 0) {
        $(document).mousemove(function(pos) {
            var thisX = pos.pageX - $this_width / 2,
                thisY = pos.pageY - $this_height / 2;

            $this.offset({
                left: thisX,
                top: thisY
            })
        });
    }

    if (xx - x < 0 && yy - y < 0) {
        $(document).mousemove(function(pos) {
            var thisX = pos.pageX - $this.offset().left,
                thisY = pos.pageY - $this.offset().top,
                ratio = ((thisX + thisY) / 2) / (($this_height + $this_width) / 2),
                height_new = $this_height * ratio,
                width_new = $this_width * ratio;

            $this.css({
                'width': width_new,
                'height': height_new
            });
        });
    }
});

$(document).on('mouseup', function() {
    $(document).unbind('mousemove');
});

これは、@ jfriend00が各要素のどこで「マウスダウン」イベントが発生するかを把握し、@JeremyCがさまざまな最適化を提供するために機能します。

jsフィドルはこちら

4

1 に答える 1

2

タイマーはまったく必要ありません。これは少なくともChromeで機能します。安全であるかどうか、すべてのブラウザでテストします。ここに行く:

var img_amount = $('.resize').length,
    height_org = new Array(),
    width_org = new Array(),
    resize_select = false,
    timer = "";

for (var i = 0; i < img_amount; i++) {
    height_org[i] = $('.resize:eq(' + i + ')').height();
    width_org[i] = $('.resize:eq(' + i + ')').width();
}

//set div width to div height * ratio to preserve aspect ratio
$('.resize').resize(function(event){
    var img_num = $(this).index(),
        height_new = $(this).height(),
        ratio = height_new / height_org[img_num],
        width_new = width_org[img_num] * ratio;

    $(this).css('width', width_new);
});

$('.resize').on('mousedown', function(event) {
    //prevent typical browser behaviour of dragging the div as an image
    event.preventDefault();

    //set z-index so the div you are dragging is in front
    $('.resize').css('z-index', 1);
    $(this).css('z-index', 2);

    $(this).mousemove(setPos);
});

$('.resize').on('mouseup', function() {
    $(this).unbind('mousemove', setPos);
});

function setPos(event) {
    var thisX = event.pageX - $(this).width() / 2;
    var thisY = event.pageY - $(this).height() / 2;
    $(this).offset({
        left: thisX,
        top: thisY
    });
}

編集:css'resize:vertical'でアスペクト比を制限するサイズ変更機能を追加しましたが、見た目が少しびくびくしています。本当にスムーズにするには、各divの右下に独自のサイズ変更ヒット領域を作成し、それにpngを追加してブラウザーのサイズ変更ハンドルを模倣してから、cssサイズ変更を使用する代わりにドラッグ機能で独自のサイズ変更を作成します。

于 2012-10-23T04:24:11.547 に答える