I've been adapting the drag-n-drop code in The JavaScript Anthology to do an R-and-D project for an intranet application that involves draggable and resizable divs with iframes inside each one. I've gotten it so that it works pretty well, but three small problems remain, particularly in IE7:
The two experimental divs with iframes often "stutter" so that the mouse goes off the div border, but the event handler stays attached so that when you move the mouse back over the div, it starts moving again, even though you're not dragging anymore. I tried attaching code to the target div's mouseout event that would unhook the move/resize event handlers, but to no avail.
It seems more difficult to grab the west and east borders than it does to grab the corners to resize. The same border and thresholds apply, so it's a mystery to me. I don't want to enlarge the div margins too much, but if that's what I need to do, please advise.
When the mouse fails to grab the border (as above), often the text in the iframe or div is selected. Any way to stop this behavior?
I've taken the standard functions from the anthology (attach and detach listeners, addLoadListener, stopEvent, getEventTarget, stopDefaultAction, and getScrollingPosition) and put them into a separate w3c_events.js file to shorten the attached code. The Frame1 and Frame3 html files can be blank, so I won't attach them either to save space.
Now, I did just find the x examples at cross-browser.com. If the general consensus is "just use those", I'd be happy to. It's just that if I've gone this far down the road, it'd be nice to not have to rip everything out.
Thanks in advance,
Jim Stanley
NTI Group
==============
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
switch(target.style.cursor) {
case "move":
case "e-resize":
case "w-resize":
case "se-resize":
case "ne-resize":
case "sw-resize":
case "nw-resize":
case "n-resize":
case "s-resize":
attachEventListener(document, "mousemove", mousemoveCheckThreshold, false);
attachEventListener(document, "mouseup", mouseupCancelThreshold, false);
break;
default:
// alert(target.style.cursor);
break;
}
// make sure the div is on top
var arrDivs = document.getElementsByTagName("div");
for (var i = 0; i < arrDivs.length; i++) {
arrDivs[i].style.zIndex = "0";
// alert(arrDivs[obj].name);
}
target.style.zIndex = "1";
stopDefaultAction(event);
}
function mousemoveCheckThreshold(event) {
if (typeof event == "undefined")
event = window.event;
if (typeof event.pageX == "undefined") {
event.pageX = event.clientX + getScrollingPosition()[0];
event.pageY = event.clientY + getScrollingPosition()[1];
}
You've applied top and bottom margin to the iframe, but no left and right margin. The mousedown event can only occur on the very edge of the element.
You should note that this script makes all DIVs on the page draggable.
Dragging has its problems. Dragging a div with an iframe adds more problems. As the mouse moves over the iframe, mouse events are no longer sent to the iframe container - they are sent to the document in the iframe. One idea is to cover the iframe with a div ('grey out' the iframe) during the drag.
Thanks much for the reply. You're right that all the divs are draggable at this point. I think I'll set a custom attribute for the divs containing a frame so the code can apply to just those divs for further work.
I twiddled with the margin settings and still wasn't able to get the sides going, even though I did see where the code was firing. I tried commenting out the threshold check before setting the event handlers and voila! I can't see any unwelcome side effects of not doing the threshold check, so if you know of any, please let me know.
Covering up the iframes makes perfect sense now that you mention it (another reason to specify which frames are draggable!). I suspect that *all* the iframes need to be covered up whenever one is dragged as I note the resizing stops if I resize too fast over another iframe.
Would you suggest creating the divs up front and positioning them when needed, or dynamic creation and removal?
Thanks again for pointing me in the right direction.
Mike, thanks again! I jiggered the code to create two transparent divs when dragging: one atop the iframe, and the other beneath the other divs. It's nearly perfect (the mouse can switch how it resizes in mid-drag but that's not really a problem) and the (internal) clients I've shown it to are quite impressed.
Bookmarks