Modernizr.prefixed(str,obj) to use Function.prototype.bind? #478

paulirish opened this Issue Jan 29, 2012 · 14 comments


None yet

3 participants


or just

 return function(){ return x.apply(navigator, arguments); }

The reason why

Some recent examples from user tests..

window[ Modernizr.prefixed('requestAnimationFrame', window) ]
battery = nav[ Modernizr.prefixed('battery', nav) ];
window[ Modernizr.prefixed('StorageInfo', window) ];

The double window/nav references kinda suck.. wondering if we just automatically bind the scope of it so we can pass back a function.


But would we only do this if the resulting thing is a function? And still just pass back a string otherwise?

how about Modernizr.prefixed('performance', window); .. pass back object or string?

Also to consider..

// so
Modernizr.prefixed('webkitMatchesSelector', HTMLElement.prototype); // return value ??

so we should make a call..what do we return?

  1. always return a string? (current behavior)
  2. return bound function in the case of functions?
  3. return actual reference for all cases (matchesSelector example disqualifies this)
  4. require a 3rd param to use as the binding scope (see comment below)
@ryanseddon ryanseddon was assigned Jan 29, 2012

a possibility for scoping for the last example from alex... use a 3rd param.

var myelem =;
var ms = Modernizr.prefixed( 'matchesSelector', HTMLElement.prototype, myelem)
if (ms('.item')) ...

That is a tough one. I would argue that this about detecting and not creating a helper method, however being both would be advantageous. I could play around with a 3rd arg and see how it feels?


I think i wanna do the autobind.


  1. bind to 2nd arg automatically if its typeof .. == 'function' (and no 3rd arg) ?
  2. require 3rd arg to opt into binding


  • what to do about objects (like window.msPerformance) and props? return references and values or string as we do it today..

Sorry was mobile earlier and couldn't chime in. I think we can do this pretty easily with something like the following:

Normal Case

// Since 'requestAnimationFrame' exists on window as a function, 
// return the function bound to window
Modernizr.prefixed('requestAnimationFrame', window)

Override to string:

// Passing false as a third param disables the possibility 
// of a function return, always a string
Modernizr.prefixed('requestAnimationFrame', window, false) // window.webkitRequestAnimationFrame

Override to other binding:

// force a binding by passing the bound object.
// This could be avoided by just passing in the element as the second param (as long as we look into prototypes).
Modernizr.prefixed( 'matchesSelector', HTMLElement.prototype, document.getElementById('theid'))

Downsides I can see:

  • Performance: it will be faster to get a string back once, and use it on all elements.
  • The case of no function being found returns a string, but when it's found it returns a function, so you'd have to test the output. This could be a bad thing.

Perhaps that means you should have to opt in for it. Always returns a string, unless you pass a third param.

pass true for us to auto use the 2nd arg, and any other object to bind to that instead.

Further if you expect a function back, the result should be falsey if it doesn't exist (instead of the raw string like in the string version of the function). A noop function could potentially work, but I haven't thought into that much.


It should be falsy return if the test fails.. which would allow for a nice rAF polyfill

window.rAF = Modernizr.prefixed('requestAnimationFrame', window) || function(){ ... 

The rest sounds good to me. I would prefer to return the function / object / prop value when possible instead of its name.

Trying to think of any prefixed property names that are just string values or numbers...


Check out some early code in the prefixed branch 16a056d

I just grabbed the Function.prototype.bind shim from es5-shim

window.rAF = Modernizr.prefixed('requestAnimationFrame', window) || function(){ ...

This will now work as expected either returning a reference to rAF of false and falling back to function

// Passing in the 3rd arg will bind to that
// e.g. ms("div") -> true
var ms = Modernizr.prefixed("matchesSelector", HTMLElement.prototype, document.querySelector("div"))

So the three possible results that this change can get:

  • false
  • reference to object
  • reference to object with binding

Also it doesn't do any hand holding so if someone tries to pass in something silly for the 3rd arg it will throw.


ryan you got a patch for this alls et?


I just merged in Ryan's branch. Considering this ticket closed code-wise but we'll have to add docs.


Okay. code and tests updated. lots of tests!

i think this is basically what @SlexAxton proposed here
#478 (comment)

I have some extra checks so we're not calling .bind() on a non-function.
i think the tests explain the API the best, but

  • if prefixed(str,obj) identifies a fn then its auto-bind()'d to obj
  • if the third arg exists and is truthy, then the fn is bind()'d to it.
  • if the third arg is false, then its always returns the stringed name of the prop/method
  • if prefixed(str,obj) finds something that is a non-function, it just returns that.

Done except for docs.


I approve this commit, good stuff!


docs added.

@paulirish paulirish closed this Feb 7, 2012
@patrickkettner patrickkettner pushed a commit to patrickkettner/Modernizr that referenced this issue Feb 22, 2015
@paulirish paulirish more robust prefixed() code and unit tests. ref #478 b82a322
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment