jquery - 移动 jquery-ui-draggable 框时的指南

标签 jquery user-interface jquery-ui jquery-ui-draggable

我正在研究如何在移动盒子时显示指南,就像在 Google 文档绘图中一样。在开始编写自己的代码之前,我更喜欢开源代码或任何类型的指南。

  1. 我不需要在多个浏览器窗口之间进行拖放,因此我不需要 HTML5 拖放。
  2. 我还使用 jquery-ui-draggable 作为盒子。

enter image description here

最佳答案

jquery ui 已经内置了这个,请参见这个演示: http://jqueryui.com/demos/draggable/#snap-to

如果您坚持遵循指南,您可能必须 fork jqueryui 或查看源代码,看看是否可以扩展它。

<小时/>

或者,您可以在 jQuery ui 之上添加您自己的捕捉功能,我已经使用它了一段时间, 虽然它看起来并不有趣,但至少它似乎也不是很难。

您可以在jsfiddle上查看示例:http://jsfiddle.net/x7uMh/103/ 更新:这有效 ~ jQuery 1.9 + jQueryUI 1.9。它在最新的 jquery+ui 中崩溃了。 懒得去看看问题到底是什么,但通常只是一些小问题。 以防万一该网站出现故障,代码如下:

CSS

body{
    font-family: courier new, courier; 
    font-size: 12px; 
}

.draggable{
    border: 1px solid #ccc; 
    display: inline-block; 
    cursor: move;
    position: absolute;         
}

.guide{
    display: none; 
    position: absolute; 
    left: 0; 
    top: 0; 
}

#guide-h{
    border-top: 1px dashed #55f; 
    width: 100%; 
}

#guide-v{
    border-left: 1px dashed #55f; 
    height: 100%; 
}
​

html

<div class="draggable">drag me!</div>
<div class="draggable">you can drag me too, if you like</div>
<div class="draggable">hep hep</div>

<div id="guide-h" class="guide"></div>
<div id="guide-v" class="guide"></div>
​

javascript(确保包含 jquery + jquery ui)

var MIN_DISTANCE = 10; // minimum distance to "snap" to a guide
var guides = []; // no guides available ... 
var innerOffsetX, innerOffsetY; // we'll use those during drag ... 

$( ".draggable" ).draggable({
    start: function( event, ui ) {
        guides = $.map( $( ".draggable" ).not( this ), computeGuidesForElement );
        innerOffsetX = event.originalEvent.offsetX;
        innerOffsetY = event.originalEvent.offsetY;
    }, 
    drag: function( event, ui ){
        // iterate all guides, remember the closest h and v guides
        var guideV, guideH, distV = MIN_DISTANCE+1, distH = MIN_DISTANCE+1, offsetV, offsetH; 
        var chosenGuides = { top: { dist: MIN_DISTANCE+1 }, left: { dist: MIN_DISTANCE+1 } }; 
        var $t = $(this); 
        var pos = { top: event.originalEvent.pageY - innerOffsetY, left: event.originalEvent.pageX - innerOffsetX }; 
        var w = $t.outerWidth() - 1; 
        var h = $t.outerHeight() - 1; 
        var elemGuides = computeGuidesForElement( null, pos, w, h ); 
        $.each( guides, function( i, guide ){
            $.each( elemGuides, function( i, elemGuide ){
                if( guide.type == elemGuide.type ){
                    var prop = guide.type == "h"? "top":"left"; 
                    var d = Math.abs( elemGuide[prop] - guide[prop] ); 
                    if( d < chosenGuides[prop].dist ){
                        chosenGuides[prop].dist = d; 
                        chosenGuides[prop].offset = elemGuide[prop] - pos[prop]; 
                        chosenGuides[prop].guide = guide; 
                    }
                }
            } ); 
        } );

        if( chosenGuides.top.dist <= MIN_DISTANCE ){
            $( "#guide-h" ).css( "top", chosenGuides.top.guide.top ).show(); 
            ui.position.top = chosenGuides.top.guide.top - chosenGuides.top.offset;
        }
        else{
            $( "#guide-h" ).hide(); 
            ui.position.top = pos.top; 
        }

        if( chosenGuides.left.dist <= MIN_DISTANCE ){
            $( "#guide-v" ).css( "left", chosenGuides.left.guide.left ).show(); 
            ui.position.left = chosenGuides.left.guide.left - chosenGuides.left.offset; 
        }
        else{
            $( "#guide-v" ).hide(); 
            ui.position.left = pos.left; 
        }
    }, 
    stop: function( event, ui ){
        $( "#guide-v, #guide-h" ).hide(); 
    }
});


function computeGuidesForElement( elem, pos, w, h ){
    if( elem != null ){
        var $t = $(elem); 
        pos = $t.offset(); 
        w = $t.outerWidth() - 1; 
        h = $t.outerHeight() - 1; 
    }

    return [
        { type: "h", left: pos.left, top: pos.top }, 
        { type: "h", left: pos.left, top: pos.top + h }, 
        { type: "v", left: pos.left, top: pos.top }, 
        { type: "v", left: pos.left + w, top: pos.top },
        // you can add _any_ other guides here as well (e.g. a guide 10 pixels to the left of an element)
        { type: "h", left: pos.left, top: pos.top + h/2 },
        { type: "v", left: pos.left + w/2, top: pos.top } 
    ]; 
}

​

希望有帮助, 最好的,汉斯。

关于jquery - 移动 jquery-ui-draggable 框时的指南,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10026234/

相关文章:

php - 通过 JSON、JQuery、PHP 传递特定信息

c# - Unity,使用 GUI 文本区域显示圈数

c# - GUI 启动时的控制台 "Hangs"

jquery - 如何在切换时删除 jQuery UI 幻灯片效果方 block

html - 'select' 元素上的 jQuery ui.datepicker

jquery - 覆盖由 jQuery 主题滚轮设置的表格宽度

jquery 在 div 的最后一个元素之前插入

linux - 重命名 trash-cli 的垃圾命令?

jquery 对话框刷新页面

jquery - 问题定位要素