Drag and Drop - Vertical/horizontal limits?

127 views
Skip to first unread message

Stern

unread,
Feb 16, 2007, 1:59:32 PM2/16/07
to Fork JavaScript
With Fork's Drag and Drop, is it possible to impose limits on the drag
movement?

Can a snippet be included in DragManager.js which would prevent any
edge of the draggable from being dragged outside the page?

Also, could the dragging be stopped even if the page width/height is
unknown? (ie., if draggable caused a vertical or horizontal scrollbar
to appear)?

Peter Michaux

unread,
Feb 16, 2007, 4:52:01 PM2/16/07
to forkjav...@googlegroups.com
On 2/16/07, Stern <ster...@hotmail.com> wrote:
>
> With Fork's Drag and Drop, is it possible to impose limits on the drag
> movement?

Yes. It is a very flexible system and overriding onDragStart and
onDrag let you programatically create any kind of behavior that you
require. This is as opposed to choosing from a reset selection of
restricted motion behaviors built into other libraries. Inevitably
they never have exactly the behavior you want.

> Can a snippet be included in DragManager.js which would prevent any
> edge of the draggable from being dragged outside the page?

There is no need to add code to DragManager.js for this. It is easy to
extend an instance of DragManager to behave as required. I've included
an example below ( don't know how the group will deal with line wraps
but it should be relatively easy to fix the wraps.)

> Also, could the dragging be stopped even if the page width/height is
> unknown? (ie., if draggable caused a vertical or horizontal scrollbar
> to appear)?

The page width and height are probably known

// Firefox and others
window.innerHeight

// IE in some modes
document.body.clientHeight

// IE in other modes
document.documentElement.scrollLeft

See Flanagan's "JavaScript" fifth edition page 276


Peter


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>restricted X motion</title>

<style type="text/css">
#basket {
position:relative;
width: 400px;
height:400px;
background:#999999;
}
#apple {
position:relative;
width:100px;
height:100px;
background:red;
}
.draggable {
cursor:pointer;
}
</style>

<script src="fork/extend.js" type="text/javascript"></script>
<script src="fork/scroll.js" type="text/javascript"></script>
<script src="fork/event.js" type="text/javascript"></script>
<script src="fork/dom.js" type="text/javascript"></script>
<script src="fork/drag/DragManager.js" type="text/javascript"></script>

<script type="text/javascript">

window.onload = function() {

var dm = new FORK.Drag.DragManager();
var basket = document.getElementById('basket');

dm.onDragStart = function(e) {
this.selectedStartX =
parseInt(this.selected.style.left.split('px')[0], 10);
FORK.Drag.DragManager.prototype.onDragStart.call(this, e);
};

dm.onDrag = function(e) {
var x = this.selectedStartX + (FORK.Event.getPageX(e) - this.startX);
if (x < 0) {
x = 0;
} else if (x+this.selected.offsetWidth > basket.offsetWidth) {
x = basket.offsetWidth - this.selected.offsetWidth;
}
this.selected.style.left = x + "px";
FORK.Drag.DragManager.prototype.onDrag.call(this, e);
};

};

</script>

</head>
<body>


<div id="basket">
<div class="draggable" id="apple" style="top:20px;left:20px;">apple</div>
</div>


</body>
</html>

Stern

unread,
Feb 17, 2007, 2:37:49 PM2/17/07
to Fork JavaScript
Wonderful! Thank you for the very helpful details!

A couple more questions:
1) Let's say that there is a link labelled "reset" which moves the
draggable DIV to a predetermined position (ie.,
document.getElementById("apple").style.left="0px") -- it seems that
the change does not take effect until the user tries to drag the DIV
again. (Maybe I'm wrong, but that's how it worked out with my test
script). Anyway, it's probably most efficient to do all this within
Fork. Could you be so kind as to show how this functionality could be
added to the above script?

2) DragManager.js has a section with the comment "HACK: Internet
Explorer hack to see if button was released outside of window",
followed by "TODO Really need prevent default?" . Personally, I think
it should be ON by default; otherwise, the draggable sticks to the
mouse cursor -- very awkward. Anyway, I enabled the hack and it works
fine with IE 6.0... but it does not work with Firefox 1.509. Is there
or will there be a hack for all browsers?

Thanks again!


Peter Michaux

unread,
Feb 17, 2007, 3:13:11 PM2/17/07
to forkjav...@googlegroups.com
On 2/17/07, Stern <ster...@hotmail.com> wrote:
>
> Wonderful! Thank you for the very helpful details!

No problem. I think I'm going to make a demo where as the mouse moves
left to right the dragged element travels in a spiral. Definitely
shows how only a couple of lines with Fork drag library can really
change the behavior.

> A couple more questions:
> 1) Let's say that there is a link labelled "reset" which moves the
> draggable DIV to a predetermined position (ie.,
> document.getElementById("apple").style.left="0px") -- it seems that
> the change does not take effect until the user tries to drag the DIV
> again. (Maybe I'm wrong, but that's how it worked out with my test
> script). Anyway, it's probably most efficient to do all this within
> Fork. Could you be so kind as to show how this functionality could be
> added to the above script?

I just tried you suggestion and it worked for me

<script type="text/javascript">
function reset() {
var el = document.getElementById('apple');
el.style.left = "20px";
}
</script>
<p><a href="#" onclick="reset();return false;">reset</a></p>


> 2) DragManager.js has a section with the comment "HACK: Internet
> Explorer hack to see if button was released outside of window",
> followed by "TODO Really need prevent default?" . Personally, I think
> it should be ON by default;

This is just a gut feeling about if it is right or wrong to have this
on or off by default. I decided for off because I want Fork to work
the same way in all browsers by default. I also don't want any hacking
in Fork and this bit of code stands out as hacking. I left the code
commented but in place so that people could turn it on if they wanted.

> otherwise, the draggable sticks to the
> mouse cursor -- very awkward. Anyway, I enabled the hack and it works
> fine with IE 6.0... but it does not work with Firefox 1.509. Is there
> or will there be a hack for all browsers?

I don't think there will be a hack for all browsers. The idea goes
against the DOM2 standards. Mouse move events do not report the button
status according to DOM2.

Peter

Stern

unread,
Feb 19, 2007, 4:11:37 PM2/19/07
to Fork JavaScript
> I don't think there will be a hack for all browsers. The idea goes
> against the DOM2 standards. Mouse move events do not report the button
> status according to DOM2.

Then perhaps the solution is to ignore whether the button is released
or not outside the window pane, but instead to just cancel the
dragging altogether when the cursor moves outside the window pane
(this.dragging = false)? Instead of the draggable "sticking" to the
cursor when it returns to the window pane (creating an awkward jumpy
movement), the draggable remains where it was left behind just before
the cursor deviated off the window?

Peter Michaux

unread,
Feb 19, 2007, 4:15:59 PM2/19/07
to forkjav...@googlegroups.com
On 2/19/07, Stern <ster...@hotmail.com> wrote:
>
> > I don't think there will be a hack for all browsers. The idea goes
> > against the DOM2 standards. Mouse move events do not report the button
> > status according to DOM2.
>
> Then perhaps the solution is to ignore whether the button is released
> or not outside the window pane, but instead to just cancel the
> dragging altogether when the cursor moves outside the window pane
> (this.dragging = false)?

You don't know if the mouse has left the window or just stopped
moving. You could analyze the momentum of the cursor and calculate the
likelihood that it has left the window. It is not an easy issue.

> Instead of the draggable "sticking" to the
> cursor when it returns to the window pane (creating an awkward jumpy
> movement), the draggable remains where it was left behind just before
> the cursor deviated off the window?

This type of behavior might work for some applications and not for
others. It could be a perfectly good solution.

Peter

Reply all
Reply to author
Forward
0 new messages