I have window with some divs that are draggable. I also have a second window that I created with window.open() that has divs that are draggable. Is it possible now to drag a div from one window to the other?
Thanks
Take a look at this tutorial for the DnD part.
To achieve this, it's possible to pass a temp value that both sending and receiving window can read. It could be a cookie, or a better idea could be to use localStorage if it's available, as some people voluntarily block cookies for more privacy.
Using the Modernizr's fallback test, it could goes like this:
if (Modernizr.draganddrop) {
// add drag and drop support
} else {
// custom drag and drop support or suggest the user to get a real browser (if possible)
}
Whenever a drag is started :
if (Modernizr.localstorage) {
window.localStorage['item_1_drag_started'] = true;
} else {
document.cookie = "item_1_drag_started=1";
}
Then, when drag is over / mouse is up :
if (Modernizr.localstorage) {
delete window.localStorage['item_1_drag_started'];
} else {
document.cookie = "item_1_drag_started=0";
}
Now, when the mouse enters the other window, you may check if the item was still being dragged by accessing localStorage (or the dirty cookie if it's unavailable).
The only issue I can think of is when the user releases the mouse button while between those windows. That could be a problem, since the item will be considered dragging but you can't release a button that isn't pressed. Does anyone know about a trick to check if the mouse button is still pressed when entering a window even if it doesn't fired the event ?
In the meantime, the click event in the receiving window could simply check if it's still dragging then drop the item and remove the flag.
UPDATE: Concerning the mentionned issue, after digging a little and doing some test with events it seems that neither mouseover or mousemove is fired when a mouse button is still pressed (at least in Chrome where my tests have been made).
With that in mind, I think that the best approach to Drag and Drop between two windows is to toggle it:
Click --> Drag is started
Click again --> Drop the item
From the answers provided I can see now that dragging between windows is really ugly. You have to basically transfer the mouse state from one window to the other and inject the element being dragged into the DOM of the destination window. I was hoping there was some jQuery around that you could run in both windows that would smooth all that over, but I guess not. I just won't do the drag in this project. I can just allow the user to click an element in the second window and have it appear immediately in the first window. Good enough. Thanks for looking at the question.
I guess you could set a variable "drag item = true" and store the item content somewhere. Then drop it on the mouse up in your popup.
What you could do is on drag being, set a cookie and on mouse over the target window, check for the cookie and simulate the drag.
Related
I'm creating a simple javacript window manager with basic functions like all windows managers(moving, resizing, depth-sorting, etc).
I'm using events like mousedown and mouseup to know when to move the window or not.
However, sometimes, when I try to move the window, chrome hooks up on it and drags the "content"(I don't know the right word to use here, just imagine you're dragging an image from the browser to your desktop), like the image below.
(My cursor is there, it just doesn't appear on the screenshot).
Whenever this happens, chrome just simply don't trigger the mouseup event when i release the button, so the windows keeps following the mouse until I click again.
Is there any workaround to make chrome don't activate its dragging system?
Thanks.
Here's a link to another question very similar to yours. It seems to have a variety of answers. Disable Drag and Drop on HTML elements?
Try adding the draggable="false" attribute to relevant elements. By default <img> and <a> elements can be dragged, as can selected text (not much you can do about that one).
Alternatively, try adding ondragstart="return false;" to the document.
I understand the event mouseup for the window just isn't there for IE 7 and 8. I was wondering if anybody has found a work-around for this or if that is even possible.
I am currently working on a project where the user can click, drag to draw a line, and if the user drags outside of the window and lets up on the mouse, the drawing transaction will be cancelled.
Your difficulty sounds like it would be more from the window losing the scope of the event.
Are you using jQuery? With jQuery you can also tag onto the mousemove event and use the "which" attribute to detect if the button is pressed. This even fires when you come back into the window. But it DOES NOT fire when you are outside of the window.
Alternatively you can use $(window).mouseleave to detect when it leaves the window. However once it has left the window you cannot detect further mouse events (that would be a horrible flaw if they could detect when you right clicked on your desktop etc).
So you are somewhat limited by the browser security implementations in ALL browsers and won't be able to bypass that... but you can add some work around events to provide a "similar" experience.
Not directly, but I believe this should work.
In your mousemove event, check the Event.buttons property. If it is zero, then the user must have released the mouse outside the window and you can cancel the drag.
I am checking the browser compatibility of this now, so this answer may be edited. My computer's being slow right now!
I have a project where users can interact with a carousel like slide show, and drag between slides instead of using an arrow/number navigation. JS is based on the following plug in:
http://nooshu.com/explore/jquery-iphone-animation/
The issue is, in IE, if a user grabs inside the carousel and the mouse leaves the container element, the UI freaks out. If you play around with it, you'll see what I mean.
Is there a way to tell IE to handle the drag/click event to mimic firefox and chrome? I'm sure this is a common problem with IE and UI design.
Help!
EDIT: This also happens in Chrome. Firefox is the only browser that handles this in an intuitive way.
When, in IE, the mouse leaves the square, it's not releasing the mousedown event. So even when you let the button go, the plugin still thinks that the mouse is down.
Is it possible then that you wrap the plugin in say a div and on the div have a mouseleave event and force the plugin to execute mouseup?
I think you should be able to use the jQuery keyword "trigger" to do it.
Gmail handles its drag-and-drop file attachment uploading in a few clever ways:
1) Dragging a file into the browser causes the dropzone to appear. The cursor displays feedback indicating whether you are in the dropzone or not (in windows, a red crossthrough circle is used if outside the dropzone). If you drop inside the window but outside of the dropzone, the drop is intercepted such that the browser's default behavior is prevented (usually navigating away to display the dragged file).
The most obvious way to attempt this is to set dragover handler on the BODY to make the dropzone appear and preventDefault, but what about the cursor change? Is there some way to use dataTransfer.effectAllowed='none'?
2) Dragging text from one part of the window into another part does not trigger the drag-and-drop handling (ie- the dropzone does not appear)--and the preventDefault mentioned in #1 does not kick in.
If I capture the dragover event on the BODY (from #1), then intra-window text dragging is prevented. How do they accomplish both of these at the same time? It seems like this is more complex than it at first might appear.
UPDATE:
I learned two related things while trying to completely address this:
1) It appears that IE will not even trigger the drop event handler if dropEffect='none'... so I decided to only set it to none if e.dataTransfer.types exists (which it does in Chrome & FF, but not in IE). The downside is that the cursor doesn't have the red crossthrough, but at least I can intercept the drop to prevent a navaway. Your best guess for determining whether it was a file drop in IE is if e.dataTransfer.getData('Text')==null. (In my case, I wanted to be able to receive drops of either files or text, so this is how I can tell the difference in IE.)
2) It was non-obvious how Gmail hides the dropzone when you leave the browser. If you use a pure dragleave event on the page, then dragging into any child will trigger the dragleave handler even though you didn't really leave the page. I then noticed that there's a delay in Gmail before the dropzone disappears, so I would guess they use a timer to hide the dropzone (which gets reset on something like dragover). But I've come up with an alternate solution that appears to work so far:
function areXYInside(e){
var w=e.target.offsetWidth;
var h=e.target.offsetHeight;
var x=e.offsetX;
var y=e.offsetY;
return !(x<0 || x>=w || y<0 || y>=h);
}
And then:
$("#page").bind('dragleave', function(e){
if(this!=e.target) return false;
if(!areXYInside(e)){
hideBox();
}
return false;
});
I believe they are setting dataTransfer.effectAllowedon dragover, depending on the dataTransfer.types attribute.
EDIT: I was wrong the first time, here are the actual values for types(in Chrome at least):
- dragging text ["text/html","text","text/plain"]
- dragging a file ["Files"]
Here is a short jsFiddle example to play around with.
You can check more info about drag and drop at w3c or mdc.
EDIT: I managed to implement the exact behavior on Chrome and FF (see here)
I'm working on a website where I'm using Javascript (via JQuery) to add pop-up boxes containing extra information for items in a list. I'm using JQuery's mouseeneter and mouseleave events to make the popups appear and disappear which of course all works fine in desktop browsers.
In Mobile Safari the popup appears when I click an item (which is what I expect and what I want to happen) and I have added an ontouchstart which triggers the mouseleave JQuery event thus hiding any visible pop-up when the user does anything else. This works fine too except that when a user taps an item the pop-up of which they've just looked at and cancelled (either by scrolling or by doing anything else that triggers the ontouchstart event), rather than it showing the pop-up again it activates the link attached to that item.
If a user were to tap another item instead of tapping the same item again then that new item's pop-up would show and then if they were to tap the first item again then that item's pop-up would show. Again, this is both expected and what I want to happen.
It would seem that once an item with a hover event has been tapped and Mobile Safari as been forced to make that event happen, that item is then flagged as having had its hover event triggered and so the next tap doesn't have to pretend to be a hover, it can be a normal click. Tapping another item with a hover event seems to "reset" the flag set for the previous item.
I'd like to be able to 'reset' this flag for myself so that, rather than how things work currently where clicking an item shows the pop-up and the next click on that item, even if the pop-up has been closed, will activate the link, instead when I close the pop-up with my ontouchstart, and so to my mind the item is no longer being "hovered over", a second click on that same item should show the pop-up again and then only by clicking on the item whilst the pop-up is visible should the link activate.
The secret would seem to be in getting Mobile Safari to exit its "pseudo-hover" mode when I use ontouchstart to trigger mouseleave but I have been unable to find anything useful anywhere on exactly what's going on when Mobile Safari pretends to hover over anything and whether any of this is accessible via Javascript events.
I know I could write a version of my pop-up code to work specifically for Mobile Safari but it seems much more efficient to me to get the browser to do most of the hard work of mimicking hover events. If only I could get this final little niggle sorted out.
I'm guessing the hover state is tied into which element has focus rather than as a flag. One tap gives focus, second tap activates the link.
Try closing the pop-up by giving another element focus, and see if that works out any better.
$('body').focus();
tl;dr but try this:
# :hover fix
# e.g.: body:not(.stoppedhovering) .styled:hover
hoverFix = ->
window.clearTimeout hoverFix.delay if hoverFix.delay?
$('body').removeClass 'stoppedhovering'
delayed = -> $('body').addClass 'stoppedhovering'
hoverFix.delay = _.delay delayed, 600
$('*').live 'touchstart', hoverFix