【问题标题】:dojo - mouse(x, y) - drag and drop - frustrationdojo - mouse(x, y) - 拖放 - 挫败感
【发布时间】:2009-08-20 03:51:32
【问题描述】:

我正在尝试使用 dojo.dnd 拖动对象,但希望头像与对象处于相同位置(相对于鼠标)

即如果有人点击对象的中间,则鼠标光标将位于头像的中间。

我得到了各种奇怪的结果。 如果我将一个函数连接到 body.onmousemove,则 dnd 的放置部分会失败。

我怎样才能让它工作?

<html>
<head>
<title>DnD Events</title>
<style type="text/css">
.target
{
border: 1px dotted gray;
width: 300px;
height: 300px;
padding: 5px;
-moz-border-radius: 8pt 8pt;
radius: 8pt;
}
.source
{
border: 1px dotted skyblue;
@ 987654337@
width: 300px;
-moz-border-radius: 8pt 8pt;
radius: 8pt;
}
.dojoDndItemOver
{
background: #feb;
border: 1px dotted gray;
}


.target .dojoDndItemAnchor
{
background: #ededed;
border: 1px solid gray;
}
.dojoDndAvatarHeader {
display: none;
}
</style>
<script type="text/javascript" src="dojo/dojo.js" djconfig="parseOnLoad: true, isDebug:false"></script>
<script type="text/javascript">
dojo.require("dojo.dnd.Source");
dojo.require("dojo.dnd.Container");
dojo.require("dojo.dnd.Moveable");
@ 987654361@
dojo.require("dojo.dnd.Avatar");
<br>var mouse = { x: 0, y: 0 , handle:undefined};
function mouseCoords(ev) {
var px, py;
ev = ev || window.event;
if (ev.pageX || ev.pageY) {
px = ev.pageX; py = ev.pageY;
} else {
px = ev.clientX + dojo.body().scrollLeft - dojo.body().clientLeft;
py = ev.clientY + dojo.body().scrollTop - dojo.body().clientTop;
}


mouse = { x: px, y: py };
// dojo.byId("msg").innerHTML = dojo.toJson(mouse);


>}
//dnd WORKS when following lines are commented out. (positioning fails)
var mchandle = dojo.connect(document, "onmousemove", 'mouseCoords');
//dojo.query(".dojoDndItem").connect("onclick", 'mouseCoords');
//dojo.dnd.Source.onMouseDown('mouseCoords')
&lt;/script&gt;
&lt;script type="text/javascript"&gt;
<br><br><br><br>

var item_price;
var total = 0;
function AddItems(target, nodes) {
for (var i = 0; i &lt; nodes.length; i++)
{ total += parseFloat((target.getItem(nodes[i].id)).data); }
dojo.byId("cost").innerHTML = total;
}


function SubstractItems(target, nodes) {
for (var i = 0; i &lt; nodes.length; i++) {
total -= parseInt((target.getItem(nodes[i].id)).data);
}
dojo.byId("cost").innerHTML = total;
}


@987654398 @
var sum = 0;
for (var i = 0; i &lt; nodes.length; i++) {
dojo.dnd.manager().OFFSET_X = 0 - (mouse.x - dojo._abs(nodes[i]).x);
dojo.dnd.manager().OFFSET_Y = 0 - (mouse.y - dojo._abs(nodes[i]).y);
dojo.dnd.manager().updateAvatar();
sum += parseInt((target.getItem(nodes[i].id)).data);
}
dojo.byId("msg").innerHTML = "Selected Item Price is $" + sum;
}


function ClearMsg()
{ dojo.byId("msg").innerHTML = ""; }


function init() {






dojo.subscribe("/dnd/drop", function(source, nodes, iscopy) {
var t = dojo.dnd.manager().target;
ClearMsg();
if (t == source) { return; }
if (t == cart) { AddItems(t, nodes); }
if (t == shelf) { SubstractItems(t, nodes); }
@987654418 @


});


dojo.subscribe("/dnd/start", function(source, nodes, iscopy) {
ShowPrice(source, nodes);
});


dojo.subscribe("/dnd/cancel", function() {ClearMsg();
});


}




dojo.addOnLoad(init);













&lt;/script&gt;

>
<br><br><br>&lt;/head&gt;
&lt;body style="font-size: 12px;"&gt;


&lt;table&gt;
&lt;tbody&gt;
&lt;tr valign="top"&gt;&lt;td&gt;
SOURCE
&lt;div dojotype="dojo.dnd.Source" jsid="shelf" class="source" id="source1" accept="red,blue"
@9 87654438@
&lt;img src="BLUE.png" class="dojoDndItem" dndtype="blue" dnddata="10" title="$10" /&gt;
&lt;img src="RED.png" class="dojoDndItem" dndtype="red" dnddata="60" title="$60" /&gt;
&lt;img src="BLUE.png" class="dojoDndItem" dndtype="blue" dnddata="13" title="$13" /&gt;
&lt;img src="RED.png" class="dojoDndItem" dndtype="red" dnddata="15" title="$15" /&gt;
&lt;img src="BLUE.png" class="dojoDndItem" dndtype="blue" dnddata="3" title="$3" /&gt;
&lt;img src="RED.png" class="dojoDndItem" dndtype="red" dnddata="148" title="$148" /&gt;
&lt;img src="BLUE.png" class="dojoDndItem" dndtype="blue" dnddata="1" title="$1" /&gt;
@98765446@
&lt;img src="BLUE.png" class="dojoDndItem" dndtype="blue" dnddata="3" title="$3" /&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
TARGET
&lt;div dojotype="dojo.dnd.Source" jsid="cart" class="target" accept="red,blue" id="target1"&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
Total Price (USD): &lt;span id="cost"&gt;0.00&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;Message: &lt;span id="msg" style="color: blue"&gt;&lt;/span&gt;&lt;/b&gt;
&lt;td&gt;
&lt;/tr&gt;
&lt;tbody /&gt;
&lt;/table&gt;
&lt;/body&gt;
@ 987654463@





【问题讨论】:

    标签: javascript dojo drag-and-drop onmousemove


    【解决方案1】:

    Dojo 的免打扰在这个意义上是有限的。化身被定位偏移,因此移动事件不会被表示拖动的节点捕获。在这种情况下,典型的源/目标将不起作用。我创建了一个混合“移动器/源”dnd 示例,它可以帮助您完成您想要完成的工作:

    http://svn.dojotoolkit.org/src/demos/trunk/beer/src/dnd.js

    基本上,我们将“mousedown”连接到某个节点。当它被触发时,我们直接在页面中原始节点的位置创建该节点的克隆(参见 _dragStart 函数)。然后,我们注册临时 mousemove 和 mouseup 事件监听器。 mousemove 是一个针对速度优化的紧凑函数。只需设置“头像”(克隆)相对于 e.pageX 和 e.pageY(标准化事件对象部分)的顶部/左侧位置。

    当 mouseup 被触发时,我们断开 mouseup 和 mousemove 事件(this._listeners)。在示例中,“overTarget”函数只返回 true。您可以将此逻辑更改为您需要的任何内容,以确保当前 pageX/pageY 坐标在您选择的边界框内(源/目标,无论您喜欢什么)。

    在示例中,我将其动画化回“源”的原始 x/y,或者将其转换为 dojo.dnd.Moveable(它是克隆节点),从来源。您可能只想使用它来将任何数据添加到您的购物车,并销毁头像。

    希望这会有所帮助。

    【讨论】:

    • 请原谅我的无知,因为我对道场还很陌生。 (我将文件命名为 beer.js 即 /dojo/beer.js)我如何实现您创建的混合? dojo.require("demos.beer.src.dnd"); dojo.require("beer.MadeDnd"); 以上全部或部分?感谢您的帮助。
    【解决方案2】:

    暂时......(因为我不知道如何实现混合js)

    我利用了取消事件,并将鼠标坐标与页面上的每个源对象进行了比较,以确定它应该被放入哪个源对象。

    页面中的JS现在是:

    var mchandle;
    dojo.require("dojo.dnd.Source");
    var lastSrc;
    function init() {
        dojo.subscribe("/dnd/drop", function(source, nodes, iscopy) {
            dojo.byId("msg").innerHTML += " drop";
            dojo.disconnect(mchandle);
        });
        dojo.subscribe("/dnd/start", function(source, nodes, iscopy) {
            lastSrc = source;
            mchandle = dojo.connect(dojo.doc, "onmousemove", "mouseCoords");
            dojo.byId("msg").innerHTML = "start";
            var px = 0;
            var py = 0;
            for (var i = 0; i < nodes.length; i++) {
                var nPos = dojo._abs(nodes[i]);
                px = nPos.x > px ? nPos.x : px;
                py = nPos.y > py ? nPos.y : py;
            }
            dojo.dnd.manager().OFFSET_X = 0 - (source._lastX - px);
            dojo.dnd.manager().OFFSET_Y = 0 - (source._lastY - py);
    
    
        });
        dojo.subscribe("/dnd/cancel", function() {
            dojo.byId("msg").innerHTML += " cancel";
            dojo.query("[dojotype=\"dojo.dnd.Source\"]").forEach(function(node, index, array) {
                var elemXY = dojo.coords(node);
                if ( //in source box
                (elemXY.x <= document.mouse.x && document.mouse.x <= (elemXY.x + elemXY.w)) && (elemXY.y <= document.mouse.y && document.mouse.y <= (elemXY.y + elemXY.h))) {
                    var s = new dojo.dnd.Source(node, null);
                    s.insertNodes(true, lastSrc.getSelectedNodes(), null, null);
                }
            });
            dojo.disconnect(mchandle);
            lastSrc = null;
        });
    }
    dojo.addOnLoad(init);
    function mouseCoords(ev) {
        var px, py;
        ev = ev || window.event;
        if (ev.pageX || ev.pageY) {
            px = ev.pageX;
            py = ev.pageY;
        } else {
            px = ev.clientX + dojo.body().scrollLeft - dojo.body().clientLeft;
            py = ev.clientY + dojo.body().scrollTop - dojo.body().clientTop;
        }
        document.mouse = {
            "x": px,
            "y": py
        };
    }
    

    Bug 仍在发生。 我拖到目标(一切都很好。) 我从目标拖动,一个重复的头像卡在屏幕上。 firebug 报错。

    _5.getItem(_6[i].id) is undefined
    } catch (e) {\r\n                                 dojo.js (line 203)
    

    您能提供任何帮助吗?

    【讨论】:

    • 错误来自 dojo.js 中的 dojo._loadPath 并且发生在 onmousemove 事件之间仅供参考
    猜你喜欢
    • 2017-08-07
    • 2012-10-14
    • 2013-10-12
    • 1970-01-01
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多