7

Is there a way to do feature detection for setDragImage of HTML5 Drag and Drop (in JavaScript or Dart)?

I do the general HTML5 Drag and Drop feature detection with the following (from guide to detecting everything):

return 'draggable' in document.createElement('span');

This will return true for Chrome, Firefox, etc., and IE10. It will return false for IE9.

Now, the problem is with IE10: While it supports most of HTML5 Drag and Drop, setDragImage is not supported and I need to provide a polyfill just for setDragImage. But I couldn't figure out a way how to detect this.

3
  • 1
    out of interest what does your polyfill for setDragImage do ?? Commented Jul 15, 2013 at 18:46
  • 1
    @Woody It manually creates an HTML Element with absolute positioning and moves it around with the mouse. To see it in action see the custom drag images example on this page with IE10. The code is here which is called here Commented Jul 15, 2013 at 22:24
  • A bit off point, here is a polyfill in case you need implementation of setDragImaage: stackoverflow.com/a/20585673/178550 Commented Sep 1, 2014 at 15:43

3 Answers 3

7

This solution assumes general D&D support has already been checked.

JavaScript (tested in IE, Firefox, Opera and Chrome):

function test() {
    var testVar = window.DataTransfer || window.Clipboard;  // Clipboard is for Chrome
    if("setDragImage" in testVar.prototype) {
        window.alert("supported");
    } else {
        window.alert("not supported");
    }
}

Dart:

I didn't find a way to do this with "native" Dart code, so js-interop is the way to go.

Sign up to request clarification or add additional context in comments.

4 Comments

Wow, works perfectly. Thank you also for the hint about Dart. If anyone finds a way about how to do this in dart, let me know!
BTW - I've created a Dart library for HTML5 Drag and Drop where I use this snippet.
@MarcoJakob Nice library! Do you plan to publish it on Pub some day? :)
It's already there: Pub html5_dnd (somehow the search on pub doesn't seem to find it...)
3

You can use the setDragImage-IE polyfill:

https://github.com/MihaiValentin/setDragImage-IE

This is how it actually works (from the README):

I noticed that if you make a change to the element's style (adding a class that changes appearance) inside the dragstart event and then removing it immediately in a setTimeout, Internet Explorer will make a bitmap copy of the modified element and will use it for dragging. So, what this library actually does is implement the setDragImage method that changes the target's element style by adding a class that includes the image that you want to appear while dragging, and then removes it. In this way, the browser displays the temporary style of the element as the drag image.

1 Comment

Nice, thank you. I had actually done something similar in Dart HTML5 dnd. But because of too many such "hacks" I finally decided to do dnd without HTML5.
2

The feature detection mentioned in the previous answer fails in Opera 12 -- because it claims support for setDragImage, it just doesn't work. The Dart libraries that have been linked to also fail entirely in Opera 12, throwing multiple errors to the console.

It's actually not possible to polyfill a ghost image -- even if you create a document element and position it in the right place, you can't get rid of the default one without setDragImage.

The only solution I know of is to filter-out Opera 12 and all versions of IE (up to and including IE11) and treat them as legacy browsers, which have to be catered for with traditional mouse-event scripting. Since the direct feature testing fails, I would recommend an indirect object test (i.e. use an object test to detect those specific browsers):

var hasNativeDraggable = (element.draggable && !(document.uniqueID || window.opera));

7 Comments

In the dart html5_dnd I switched to using an (evil) browser detection: window.navigator.appName == 'Microsoft Internet Explorer'. The example should work in IE9 and IE10. I don't know about IE11. And Opera might be a problem, yes.
You can also detect IE with if(document.uniqueID), which can't be changed by the user. Might be nice to at least filter Opera so it doesn't throw errors. Opera 12 is still the dominant version (regular users aren't upgrading to the webkit builds, because they're not good enough)
Thanks. I've filed an issue for this.
btw -- the drag behaviors works in IE11, but the custom ghost image doesn't, it just shows the default. How did you make that work in IE10 -- how did you hide the default ghost to stop it from showing up as well as the custom image? Since I didn't know that was possible, I've assumed that you'd want to filter all versions of IE from native support; but if you're keeping IE and only filtering Opera 12, then you won't need the document.uniqueID test: var hasNativeDraggable = (element.draggable && !window.opera); //all supported browsers except opera
It's not possible to hide the drag image in IE10 (like you said in your answer). I just emulate the dragging in IE10 and don't use HTML5 draggable whenever a custom drag image is used. I'm glad you didn't see much of a difference :-). You can recognize it when you look at the drag cursor in IE10. Instead of the HTML5 draggable cursor, the cursor is set by CSS.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.