I've been searching for this for a couple of days now and so far, the best I can come up with is checking the list below. I really don't like to check for support based on User-Agent, especially since it can be spoofed. I've also heard of at least one instance where the list below is incorrect (noted below).
- Is Internet Explorer?
- Is WebKit? (But I've read that mobile Safari doesn't support it)
- Is Opera?
- Is Gecko and version >= 1.9? (meaning Firefox 3 or later)
Is there a better method based on testing for support directly via JavaScript, or is this pretty much the only way to test for support?
The best way to check for a certain feature is to actually test for that feature on an element that you know should support it, like this:
or
The best solution for my scenario (similar to yours) I came up with is below. It's not probably bulletproof, but covers most of the situations:
You can test it out in this jsFiddle.
Notice: Depending on your needs and purpose, you might need to detect IE version as well, because it's support of contenteditable is ... "not ideal" :-) Most of the pains is dealt by super library Rangy.js.
bobince's answer works for the most part but, as has been said, you will need user agent sniffing to exclude iOS and Android versions that don't bring up the software keyboard. I'm currently using something like this:
This should stop older iOS and Android devices from returning true. It still has one problem though: physical keyboards. If, for example, a device is running Android 2.3 but has a physical keyboard then the user will be able to use contentEditable but this function will return false. Physical keyboards are quite rare though.
More commonly, on some devices it may be possible for the user to bring up the on screen keyboard by pressing and holding the menu button. Obviously this isn't really something you should expect your users to know about.
You could mitigate these issues slightly by having some way for the user to manually override the sniffing part of the detection script. You could implement this in the isContentEditable function by adding an override check to "if (canEditContent)". However, Implementing the UI for this might present more of a challenge ;).