Category Archives: Code

Native smooth scrolling with JS

There’s a new way of invoking the scroll functions in JavaScript where you can specify how do you want the scroll to behave: smoothly, immediately, or auto (whatever the user agent wants, I guess).

window.scrollBy({ top: 100, behavior: 'smooth' });

(note it’s behavior, not behaviour, argggh).

I read this post yesterday saying that it would be available (via this tweet from @FirefoxNightly) and immediately wanted to try it out!

I made sure I had an updated copy of Firefox Nightly—you’ll need a version from the 28th of October or later. Then I enabled the feature by going to about:config and changing layout.css.scroll-behavior.enabled to true. No restart required!

My test looks like this:

native smooth scrolling

(source code)

You can also use it in CSS code:

#myelement {
  scroll-behavior: smooth;
}

but my example doesn’t. Feel like building one yourself? :)

The reason why I’m so excited about this is that I’ve had to implement this behaviour with plug-ins and what nots that tend to interfere with the rendering pipeline many, many times and it’s amazing that this is going to be native to the browser, as it should be smooth and posh. And also because other native platforms have it too and it makes the web look “not cool”. Well, not anymore!

The other cool aspect is that it degrades great—if the option is not recognised by the engine you will just get… a normal abrupt behaviour, but it will still scroll.

I’m guessing that you can still use your not-so-performant plug-ins if you really want your own scroll algorithm (maybe you want it to bounce in a particular way, etc). Just use instant instead of smooth, and you should be good to go!

SCROLL SCROLL SCROLL SCROLL!

Update: Frontender magazine translated this post to Russian.

Binding to an specific host with express.js

The documentation on the listen method is really vague, but the way you can make your server listen to an specific address only is this:

var server = app.listen(3000, '127.0.0.1', 511, onServerListening);

In this case I want the server to respond only to connections using the 127.0.0.1 host name. Not 0.0.0.0, and not localhost. Only 127.0.0.1.

The reason for this is that I am playing with Twitter’s OAuth and I was stumbling upon this issue because express insisted in binding to 0.0.0.0 by default (i.e. any address), but it wouldn’t work well when Twitter redirected back after authenticating.

For reference, another thing I tried and didn’t work:

var server = app.listen(3000, '127.0.0.1', onServerListening);

Notice that the 511 parameter is missing. So effectively it would take onServerListening as if it was the 511 parameter, which according to the documentation is “the maximum length of the queue of pending connections” and it wouldn’t call the callback. Booo.

window.devicePixelRatio

If you want to write code that looks nice and crispy in high density displays, you have to take the device pixel density into account. This is exposed to us in JavaScript as the window.devicePixelRatio property, which returns a number that describes how many physical pixels does it take to represent a device independent pixel. The more pixels it takes, the finer the display will look, and the harder it is to actually “see” individual pixels (as in, individual, physical light dots) in the screen. This is famously known now as the “Retina” effect, but not only Mac products exhibit this behaviour-most relatively high end phones with “touch screen” usually have a display density higher than 1.

The interesting bit here is that you can’t assume that once a document is opened in your browser, the devicePixelRatio will stay constant. If you drag the window to a screen with a different density, this value will change–as seen in this video where I am dragging my test page window between the Retina display of the laptop, with ratio = 2, and the external monitor whose ratio is 1. For comparison, devicePixelRatio is 3 on my Nexus 5, 1.5 on a Firefox OS Flame, and 1 on a Geeksphone Keon.

Try it out, and maybe leave a comment with what you got!

There isn’t any event triggered when this value changes, so that’s why in this test case I set a periodic interval to keep updating the value:

setInterval(updateDPR, 50);

function updateDPR() {
    p.textContent = window.devicePixelRatio;
}

Perhaps not the most efficient piece of code, but this is also a bit of a corner case maybe, and a test page, so just don’t copy it literally :-)

Sources.

What does the Battery API report on a desktop computer?

I was discussing with Chris Mills how to build an example for Web APIs that was clear enough yet showed some sort of API usage in action. He had chosen the Battery API which is, effectively, simple enough. But I had a question: what does this API report when you run it in a device without battery?

Nothing better than building an example, so that’s what I did.

On a laptop

It reports the battery level and discharging / charging, plus the time left, if not at the maximum level already.

battery api on a laptop

On a desktop

It reports battery level at 100%, charging, and 0 seconds to charge.

battery api on a desktop

Mystery solved!

A final note/remark: while going through the API docs I found it so very synchronous and unpromise-y! If this API was written nowadays it would probably be done with Promises or some sort of asynchronicity by default. I wonder if that will be retrofitted.

Failproof AJAX requests in Firefox OS

Have correct values in the manifest

The app type has to be at least privileged. No, web (hosted) apps won’t work with different domains if CORS is not enabled there.

Add the systemXHR permission too, or your XMLHttpRequests to domains without CORS enabled will instafail.

Example of the syntax for these two things in the manifest:

{
  "type": "privileged",
  "permissions": {
    "systemXHR": {
      "description": "Allows loading remote content"
    }
  }
}

Add the “magic word” when creating XMLHttpRequest objects

The magic word being the mozSystem property:

request = new XMLHttpRequest({ mozSystem: true });

You should now be able to use the request in the usual way. Remember to add an error handler in case it fails!

We are using these superfailproof requests in our privileged app template to load definitions from MDN. Have a look!

For more info