(drag n) drop files in Firefox - javascript

Because a demo is worth 72.814 words: http://jsfiddle.net/rudiedirkx/J575b/3/show/
That's the simplest demo. Three events: drag over, drag leave and drop. over and leave work as expected (the class is added and removed). The drop however doesn't!
Like IE, it opens the dropped file in the window. In Chrome the event cancels and the dragging file is dropped (and ignored in this case).
The drop event doesn't even trigger in Firefox!?
What's going on? I thought this worked... (It does in Chrome. It doesn't in Opera 11.64.)
EDIT
Fixed, thanks to Adriano: http://jsfiddle.net/rudiedirkx/J575b/5/show/

Change your ondragover handler to this:
drop.ondragover = function() {
this.classList.add('over');
return false;
};
Note the return false line, from Mozilla.org you need to preventDefault() or return a false value from the function to allow the drop.

Related

Chrome: Inspect elements that appear only when dragging

I often want to view the styles of an element that appears only when dragging or when the mouse is clicked (mousedown event). How can I view the element's style using Google Chrome's developer tools?
Open the developer tools.
Go to "Sources":
Expand "Event Listener Breakpoints" on the right:
Add a listener for keydown events on the keyboard section:
Now start dragging the thing you want, and when it's time press any key on your keyboard and you'll be able to inspect the dragable element.
You can simply press F8 while dragging (and developer tools is open)
In case anyone encountered this question in the future, I have another solution for this. This solution is kinda same with the most upvoted answer, but it doesn't require any keydown, just simply drag:
Open chrome devtools
Click on the Sources tab
Go to Event Listeners Breakpoints down there
Om the event list, click Drag / drop, then tick dragover
After that, whenever you start to drag an element, the browser window will pause for debugging, then you can inspect the element's CSS styles freely.
Note: I tested this on Chrome version 80, but I think it works in older version though.
Edited:
Just now I figured out dragover breakpoints doesn't work in certain condition, e.g., if you want to inspect styles after the dragged item reached another element. For that situation, you may try different listeners as specify in Drag / drop, such as drop.
dragMethod() {
setTimeout( () => {
debugger;
}, 500)
}
This will suspend the drag action so you can proceed to inspect as normal.
From the DevTools Go to the lowest element that will wrap your draggable item
Right click this element and chose "Store as global variable" it'll be referred to from the console as temp1
Write in the console this command - let myInterval = setInterval(() => console.log(temp1.cloneNode(true)), 1000)
At this stage you can see the element details in the console whem you drag it.
When you don't need to inspect it any more run from the console - clearInterval(myInterval).
Instead of section 2 you can run the follow command and select your draggable element with the appropriate query selector - let myInterval = setInterval(() => console.log(document.querySelector(/* your query goes here */)?.cloneNode(true)), 1000)
Put a breakpoint in the code - inside of the mousedown event callback.
This will freeze the app when you begin dragging, and then you can tab over the the Element section of the inspector to use it like you normally would, only now it's frozen at the beginning of the drag.
EDIT: You should put the breakpoint on a line below where the new elements you want to inspect are created, so the elements are on the DOM by the time you freeze.
// Raw event
someElement.addEventListener('mousedown', function(ev) {
// Put a breakpoint on any of the lines in here
}, false);
// jQuery for prudence
$(someSelector).on('mousedown', function(ev) {
// Put a breakpoint on any of the lines here
});
One way of doing it is to open the elements panel then right click while dragging.
This opens the contextual menu and "pauses" the mouse move/hover effect.
Then after right clicking, go back to the elements panel and search for the element using the find feature.
This can also be used to inspect hover effects (it's just faster than other methods)
This can be tested here for example
https://jqueryui.com/draggable/#visual-feedback
In addition to #Davids answer, it might be worth mentioning, that you need to add a eventlistener somewhere in your code as well or simply put it in the console before
Example:
document.onclick=function(){};

incorrect behavior 'onselectstart' in Chrome

There is draggable element which must move with a 'move' cursor. The cursor will become like at selecting when I move the element. I tried to use .onselectstart = function(e) { return false } on 'mousedown' and .onselectstart = null on 'mouseup'. It works good. But it stops working after any select on the page. I observe it in Google Chrome and Maxthon only.
So, take a look http://jsfiddle.net/JqMgE/1/
Sometimes needs select a few times to call this bug.
I solved the problem by using event.preventDefault() onmousedown and onmousemove.
http://jsfiddle.net/JqMgE/2
There is no need to use .onselectstart.

javascript dragging a file from desktop: dragenter / dragleave triggers uncorrectly

Made a fiddle for this: http://jsfiddle.net/terjeto/MN4FJ/
My problem is that dragleave fires when you drag a file from desktop into the box and over the text inside the box. (drag a file into box will make the border solid -> drag the file over the text inside the box and the border will be dashed:->which is not what I want).
Is this a browser bug? (firefox 9#win).
I also put in a box for mouse up/down which works just fine so you can compare the two.
How can I achieve the correct dragenter / dragleave behaviour?
PS. I bind to body because I need the event-delegation in my real app.
This is a well documented shortcomming of the spec.
As Peter-Paul Koch points out here
A function like this might help you work out if the target element is a child of the target area that you want to drop the file onto.
function isChildElement(parent, child) {
var childParent = child;
while (childParent) {
if (childParent == parent) {
return true;
}
childParent = childParent.parentNode;
}
return false;
},
I've written a little library called Dragster to help me deal with this issue, it works everywhere except IE (where it just does nothing).
The issue is relatively well known, but solutions are all pretty 'hacky'. I came across a workaround that fixes it in my case and should be adaptable for most situations.
I listen for dragenter events on the container (a box) of my possible dropzones. Events fire whenever the drag moves from one element to another and bubble to the container. When the target is one of my drop zones (or possibly a child within the drop zone but that wasn't necessary in my case since you can't get to the children without entering the surrounding box first) then I set the droppable highlighting, just as normal.
When the dragenter event fires on the container itself then I remove the highlighting from the previous element because I must have left it. For a dragenter event, the element that was highlighted is the relatedTarget so it is easy to find and there is no need for a dragleave event listener.
Note that you may have the remove the highlighting explicitly following a drop, depending on your exact drop logic.
I had the same problem and finally figured out a stable solution. Here is a plugin called draghover, which works cross browsers. Check it out here: https://github.com/bingjie2680/jquery-draghover

jQuery - click-event is called twice on iPad

I have a problem with my web application which is designed for iPad.
I use jQuery and jQuery UI for dragging elements on the screen. Because on iPad, the element can not be dragged by default, I added this library:
http://code.google.com/p/jquery-ui-for-ipad-and-iphone/
Including it, I can drag and drop elements on iPad, but also a problem occurs. I have on the draggable element also a div are with an image, which should be clickable.
So I integrate these lines:
$(document).ready(function() {
$(".note").draggable();
$('.closebutton').click(function() {
alert("test");
});
});
​
The problem is, including the drag-library, the alert message test pops up twice or the screen is frozen.
I created a full working demo here:
http://jsbin.com/oliwo/2/
On normal desktop browsers, like Firefox 4 Beta and Safari, it works, only one test message appears by clicking with the mouse on the x - delete image. On iPad, I get the message twice or the screen froze.
Does anyone can help me? Thank you a lot in advance & Best Regards.
This is not really a response, as i don't known why you have it twice. But you can try a workaround if you're sure your click event is the only click event behavior that should be attached to this button; Make an unbind() just before you're bind, this will remove any previous click binding (so if this is run several times, you'll get only one event):
$('.closebutton').unbind().click(function() { ...
or better:
$('.closebutton').unbind('click').click(function() { ...
I've found that events get fired twice when showing an alert box on a click. I've managed to overcome this problem by using a setTimeout to show the alert box...
$("#myButton").unbind("click").click(function () {
// Have to use a setTimeout else on iPhone the alert may appear twice in certain scenarios
setTimeout(function () { alert('The message'); }, 300);
return false; // Return false to prevent href being followed
});
I do not know why, but if I do not use alert messages, it will work. I create new elements and then it is only called once, on iPad and Desktop Safari.
I'm seeing this issue only on iPad, perhaps some version of webkit related. The unbind worked for me, and I also read this only exists if jquery code is in the body html tag, if its in head it is not an issue.
just simply avoid the propagation of the click
$("tr").live('click',function() {
...
$( event.toElement ).one('click', function(e){ e.stopImmediatePropagation(); } );
});

Javascript detect when drop down list is closed

Because of the issue explained in this question I have a situation where I need to attach the mousewheel event to the drop down list only when it is expanded (I do this in the onclick event). However I need to remove the mousewheel event when the list collapses. How do I go about detecting this?
I can't just use the onchange event because the user may not have actually changed their selection. I've tried the onblur event but in most browsers (except IE) the drop list stays focused when the list is collapsed.
Cheers.
var list = document.getElementById("list");
list.onclick = function (e) {
// attach mousewheel
list.onmousewheel = function (e) {
// ...
}
// attach click off
// This event fires fine in all browsers except FF when the list is expanded.
// In firefox it only fires when anywhere in the document is clicked twice.
// The first click closes the drop down list as expected and the second one
// fires the event.
window.document.onclick = function (e) {
list.onmousewheel = null;
window.document.onclick = null
}
};
EDIT:
Unfortunately meder's solution doesnt work in firefox. The click event on the document doesn't get fired until i click twice off the drop down list. How do I get around that? It works fine in IE.
EDIT2:
I've done some more testing and the following browsers behave as expected
IE 7,
Chrome 3
Opera 10
Firefox requires 2 clicks in the window to make it work & Safari doesn't work at all.
It appears that even when you click off the drop down list firefox maintains focus on it. It's not until the second click occurs that the drop down list eventually loses it's focus.
Are you looking for something like this? If the user clicks anywhere that's not within #el, it will branch out and you can do what you want, though this requires jQuery but it would take far too many lines of DOM Scripting.
var dropdown = $('#el');
$(document).click(function(e){
if ( (!$(e.target).is(dropdown)) || !$(e.target).closest('#el').length ) {
// do what you need to
}
});
If not, can you be more specific and include an example?
PS - I did not test the snippet, sorry if it isn't what you want.
OK, I still have no idea what you're trying to achieve with such a tightly-scripted select box, but in general trying to change the internal working of a native <select> isn't fruitful. There's no standard that says how events flow internally to the form element, and browsers that implement select as an OS-level widget (IE) can't do much to support it anyway.
If you must have this behaviour, I'd suggest using scripting to replace the <select> box on-fly with a JavaScript-powered analogue made out of <div>s. Then you can control exactly how each mouse and keyboard interaction behaves. There are many libraries that do this already, though again if you need to be very specific about the exact behaviour they might not suit you.

Categories

Resources