47

I'm trying to write a simple placeholder jQuery plugin for a site of mine but of course I only want to fire the function if the native placeholder attribute isn't supported…

How can I use jQuery to test for native support of the placeholder attribute?

tshepang
  • 12,111
  • 21
  • 91
  • 136
Jannis
  • 17,025
  • 18
  • 62
  • 75

4 Answers4

93

You can add to $.support quite easily by inserting this at the top of the Javascript you've written:

jQuery.support.placeholder = (function(){
    var i = document.createElement('input');
    return 'placeholder' in i;
})();

You can then use either $.support.placeholder or jQuery.support.placeholder anywhere in your code.

NB This code adapted from diveintohtml5, the link provided by hellvinz above.

Binarytales
  • 9,468
  • 9
  • 32
  • 38
lonesomeday
  • 233,373
  • 50
  • 316
  • 318
  • This is brilliant and exactly what I was looking for. Thank you. PS: Thanks for the link, great resource. *Bookmarked!* – Jannis Oct 14 '10 at 22:08
  • Thank hellvinz, not me, for the link! What's more, it would be trivial to create a plugin that imports all Modernizr tests to `$.support`. A quick test reveals that it would be a 11kb file once minified. – lonesomeday Oct 14 '10 at 22:31
  • even if all i want to test for is form functionality? – Jannis Oct 15 '10 at 21:27
  • No, that's for the whole library. I've rewritten the diveintohtml5.org HTML5 form code as a plugin to extend `$.support`. It's at http://pastebin.com/NVs09xzX at the moment and I'll put it on the jQuery site as a plugin soon. – lonesomeday Oct 15 '10 at 22:20
  • Hey, thanks for your comment! That little plugin is exactly what I needed. Do you mind if I include it in my jquery plugin that I'm writing at the moment? – Jannis Oct 16 '10 at 23:59
  • 8
    I like the solution (if you are not using Modernizr), but the `'placeholder' in i` is actualy a little bit more performance heavy to perform than `i.placeholder !== undefined` due to the fact that the script has to map ALL the objects attributes before the check is performed. Not a big change, but everything counts and generally the `[some att] in [some object]` should be avoided if possible for the reason mentioned. – Tokimon Jan 31 '13 at 15:06
  • Note that this technique obviously works without jQuery as well. – Christopher Schultz Mar 19 '14 at 21:55
  • Can't this be shortened to `$.support.placeholder = document.createElement('input').placeholder !== undefined;`? – David Harkness Aug 06 '14 at 23:42
  • 1
    Be aware that jQuery says about `$.support`: `Intended for jQuery's internal use; specific properties may be removed when they are no longer needed internally to improve page startup performance.` https://api.jquery.com/jquery.support/ – rakslice Aug 25 '14 at 23:35
15

Use the Modernizr library, which you can find here: http://www.modernizr.com/

And then do this:

if (Modernizr.input.placeholder) {
  // your placeholder text should already be visible!
} else {
  // no placeholder support :(
  // fall back to a scripted solution
}

Modernizr is really handy for testing the browser's support for almost all HTML5 functionality.

Ender
  • 14,995
  • 8
  • 36
  • 51
  • Thanks for your answer. I am already using Modernizr in my document however for this plugin to work on all sites I don't want to rely on any external libraries such as Modernizr other than jQuery of course. On my current page that I am building this indeed works great, but just for general compatibility I'd prefer something not reliant on Modernizr. – Jannis Oct 14 '10 at 21:50
4

I like having such a simple class ...

var Browser = {
  Can: {
    Placeholder: function () {
      return 'placeholder' in document.createElement('input'); 
    }
  }
}

... so you can easily check if your browser supports the placeholder attribute.

if (Browser.Can.Placeholder()) {

}
ˈvɔlə
  • 9,204
  • 10
  • 63
  • 89
3

The placeholder property exists on INPUT DOM objects in all browsers regardless whether or not the placeholder attribute has been defined on the HTML INPUT element.

The correct way is:

var Modernizr = {};
// Create the input element for various Web Forms feature tests.
var inputElem = document.createElement('input'), attrs = {};    
Modernizr.input = (function(props) {
    for(var i = 0, len = props.length; i < len; i++) {
        attrs[props[i]] = props[i] in inputElem;
    }
    return attrs;
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));

if(!Modernizr.input.placeholder) {
    // Do something.
}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343