Function.prototype.bind

Modernizr 2.5 added lots of robust feature detects and tests, but perhaps its most convienent feature is the addition of a Function.prototype.bind polyfill. In short, .bind() allows you to set this within a function.

As I employ prototypal objects and class methods a lot, I’m using .bind() a bunch. It’s helpful within setTimeout:

function ClassAct() {
  this.generation = Math.floor( Math.random() * 10 + 4 );
  this.name = 'James J. Jones, the ' + this.generation + 'th.';
}

ClassAct.prototype.sayHello = function() {
  console.log('Gday! I am ' + this.name );
};

// old, ugly way
ClassAct.prototype.sayDelayedHello = function() {
  // can't use `this` in here, because it will be set to the `window` object
  // have to hack it with local `_this` var
  var _this = this;
  setTimeout( function() {
    _this.sayHello();
  }, 1000 );
};

// with Function.prototype.bind()
ClassAct.prototype.sayDelayedHello = function() {
  setTimeout( this.sayHello.bind( this ), 1000 );
};

Or, you could use it for quick and easy event handling:

function ClassAct() {
  // say hello on click
  // without .bind( this ), `this` in sayHello() will not be ClassAct instance
  document.addEventListener( 'mousedown', this.sayHello.bind( this ), false );
}

See it in action: here’s a fiddle to compare using .bind() within class methods: Without Function.prototype.bind and with Function.prototype.bind.

Slicing arguments

In the jQuery Plugins Authoring tutorial, Ralph Holzmann details an intriguing pattern for plugin methods:

var args = Array.prototype.slice.call( arguments, 1 );
return methods[ method ].apply( this, args );
// (edited for clarity)

As the tutorial explains, this pattern is what enabled jQuery UI plugins to have multiple methods. Indeed, If you look deep within the coils of jQuery UI widget factory, you’ll find it there as well:

var args = slice.call( arguments, 1 );
instance[ options ].apply( instance, args );
// (again, edited for clarity)

I had thought of this argument-slicing method pattern just as another bit of JavaScript witch-craft that seemed to work, but I had no comprehension of why.

Today, I’m working on a sort of particle/field class and this pattern finally clicked. Here’s what I’m working with

// field has multiple particles
function Field() {
  this.particles = [];
  for ( var i=0; i < max; i++ ) {
    this.particles.push( new Particle( i ) );
  }
}

// particles have methods
function Particle( index ) {
  this.index = index;
}

Particle.prototype.logIndex = function() {
  console.log( this.index );
}

If I want logIndex on each particle in a field, I would have to loop through each particle and call its method.

Field.prototype.logParticleIndexes = function() {
  for ( var i=0, len=this.particles.length; i < len; i++ ) {
    this.particles[i].logIndex();
  }
}

This is all fine and well when you only have a couple methods in a field that have to iterate over each particle. But you could create another method that was more flexible, and trigger a method passed in from an argument.

Field.prototype.eachParticleDo = function( methodName ) {
  for ( var i=0, len=this.particles.length; i < len; i++ ) {
    this.particles[i][ methodName ]();
  }
}

myField.eachParticleDo('logIndex');

But if the particle has method that require arguments, we’ll need a way to pass those arguments in.

Particle.prototype.setColor = function( color ) {
  this.elem.style.backgroundColor = color;
};

This is where argument-slicing comes in.

Field.prototype.eachParticleDo = function( methodName ) {
  // pass in any other arguments after `methodName`
  var args = Array.prototype.slice.call( arguments, 1 );
  var particle;
  for ( var i=0, len = this.particles.length; i < len; i++ ) {
    particle = this.particles[i];
    // first argument, particle, is what `this` will be inside function
    // second argument is the arguments for that function
    particle[ methodName ].apply( particle, args );
  }
};

myField.eachParticleDo( 'setColor', 'blue' );

Let’s break down what’s going on up there. In order to get any arguments after the first one, methodName, we need to remove methodName from arguments. With a normal array, we could use ary.slice( 1 ). But because arguments is a bizarre array-like object, we need to use an equally bizarre method to slice it. For more on this, See Sebastiano Armeli’s Understanding Array.prototype.slice.apply(arguments) in JavaScript.

Now that the arguments are in a proper array, they can be used as the arguments with .apply(). Per flatline on Stack Overflow What is the difference between call and apply?:

The main difference is that apply lets you invoke the function with arguments as an array; call requires the parameters be listed explicitly.

Nice. Here’s a quick particle demo with eachParticleDo in place.

See fiddle: Particle field with .eachParticleDo

Try opening up the raw fiddle with your console and enter.

myField.eachParticleDo( 'setColor', 'red' )

WebKit zoomed-out font-size threshold

The zoomed-out font-size threshold in WebKit is a mysterious anomaly I’ve long had my suspicions about, but now have finally tested. Take some body copy, start zooming out the page, and observe how copy with smaller font-sizes seem to maintain some legible size, even though they should be much smaller. Try hitting ⌘- too see the effect on this fiddle.

View fiddle - zooming font-size threshold

Here’s how Chrome 16 renders the fiddle with Zoom Out hit twice. Zoomed-out font-sizes 13px-9px are all rendered as the same size. Smaller font-sizes return to proper proportions. Note that this is not Safari’s preference to limit small font-size, as the teeny-tiny font-sizes are still rendered.

WebKit zoomed-out font-size threshold

Zooming out four times, it appears that the threshold is setting a font-size to 9px. Any text set to 9px font-size or greater will be rendered at least the minimally-legible size of 9px. Anything smaller will be rendered proportionally.

WebKit zoomed-out four times. Font-size 9px threshold

Subpixel positioning with CSS transforms and type rendering

Along with WebKit hardware-accelerated anti-aliasing, CSS 3D transforms can have adverse effects on type rendering when translate X/Y values have subpixel, or decimal values.

View fiddle: Subpixel type rendering. Hover over elements to disable transforms.

In WebKit, the first two elements will have fuzzy type and borders, as rendered elements don’t exactly line up with pixels on the screen.

Just to be thorough, I took a look at 2D subpixel translation transforms (i.e. translateX(0.5px)). In WebKit, the type seems to render appropriately with the subpixel values. However the borders don’t look so good. They get positioned in between pixel spaces, rendering a 1px border with 2 pixels. Firefox doesn’t have any issues with borders.

subpixel transform positioning type rendering screenshot

The fix is to prevent decimal values when using translate and round those values to the nearest integer.

Resolving anti-aliasing on WebKit hardware-accelerated elements

Activating hardware acceleration in WebKit with 3D CSS transforms changes the way WebKit renders text. WebKit composites the element so that when rendering the transform, it doesn’t have to re-render sub-pixel anti-aliasing for every frame. This feature is a good thing in that vastly improves performance of transitions and transforms in WebKit.

But this affects anti-aliasing when there is no actual transform and hardware-acceleration is active on a element. i.e. banal 3D transforms like translate3d( 0, 0, 0) or scale3d( 1, 1, 1 ).

The solution is the same one for IE’s opacity bug: add a matching background to the affected background.

View fiddle: resolving anti-aliasing with hardware acceleration.

Hover over the image below to see the comparison for TUAW.

See also Webkit Hardware acceleration bleeding into subsequent elements, and how to fix it - The Official Posterous Tech Blog.

Named access on the window object

Per the HTML5 spec, you can access elements via their id. For example, on dropshado.ws, which has markup of <section id="posts">...</section>, plugging in window.posts or posts in the console will return the HTML element.

document.getElementById('posts')
// >> <section id=​"posts">...</section>​
window.posts
// >> <section id=​"posts">...</section>​
posts
// >> <section id=​"posts">...</section>​
posts === document.getElementById('posts')
// >> true

From my brief tests, WebKit and Opera support this, not Firefox 4.

Global HTML element with ids fiddle

The good news is that this is a convenient for debugging, no need to type out document.getElementById. Bad news is that its not especially reliable. See also this WHATWG thread polluting global namespace and other concerns.

Trigger event methods

Looking into triggering events without jQuery. Turns out you can just use some events as methods, for example .click() or .blur(). I’d love to find a listing reference for these methods, but haven’t found one yet.

I’m using .blur() to dismiss the iOS keyboard once a text input has been focused.

var input = document.getElementById('input'),
    button = document.getElementById('button'),
    onClick = function(){
      input.blur();
    };

button.addEventListener( 'click', onClick, false);

See fiddle: trigger blur to dismiss iOS keyboard

Removing a jQuery object from another jQuery object

Working on Isotope, I have a scenario where I need to remove a jQuery object from another jQuery object. Item elements are cached within the plugin’s instance. If the user needs to remove those elements from the DOM, they need to also remove them from the cache.

The solution is to use the .not method.

// removes $b from $a
$a = $a.not( $b )

You need to assign the result of the statement back to the original jQuery object. Using just $a.not( $b ) will not affect $a.

See also How to remove an element from jQuery object? - Stack Overflow

Remove items from jQuery object fiddle

left / top / right / bottom positioning

So many gems within Jordan Dobson’s animated border demo, but I especially like his use of positioning with all four directions.

left: 0;
top: 0;
right: 0;
bottom: 0;

With no size dimensions set, the child element stretches to the size of its parent. Typically, when I want a absolutely-positioned element to match its parent, I’ll use left: 0; top: 0; width: 100%; height: 100%;. The pattern employed by Mr. Dobson affords calculated margins, i.e. the child element can extend to within 10px of its parent.

View “left / top / right / bottom positioning” fiddle

#color keyword values

WebKit parses #colorkeyword values as valid colors. background: #yellow renders as yellow.

#color fiddle

Being thorough, I also tested other color values with an extra # in front. No dice, only keywords get parsed.

Max border-width

Some browsers max-out border-width. In the fiddle below, where I set border-bottom-width: 9999px, WebKit browsers render only 1807px, Opera renders 2407px. Like a mad scientist, Firefox renders all ten-thousand-minus-one pixels.

Max border-width fiddle