/dev/nikc/blog

Kuolleiden purjehduskenkien seura

Dec 3rd 2013

Managing scrollTop in your Backbone single-page app

19:04

One of the great caveats of single-page apps is that they rely on taking over many of the browser's default behaviours. One of the more significant ones is how the browser behaves on page-to-page navigation, be it forwards or backwards. By default, the browser will take you to the top of the page when you navigate forwards by following a link. In contrast, you expect to be returned to the position on the page where you followed a link, when you use your browser's back-button.

In case you happen to be using Backbone to power your single-page app, this behaviour can be restored with very little effort and code. Unfortunately, this will only work in browsers supporting the History API, so old-IE (IE 9 and earlier) users are out of luck.

To pull it off, a global navigation event listener is used to store the current scrollTop just-in-time.

// A global a.onclick event handler for all your navigational needs
// see e.g. Backbone Boilerplate for a more complete example
$(document).on("click", "a", function (ev) {
    ev.preventDefault();

    // Replace current state before triggering the next route, 
    // storing the scrollTop in the state object
    history.replaceState(
        _.extend(history.state || {}, { 
            scrollTop: document.body.scrollTop || $(document).scrollTop() 
        }),
        document.title,
        window.location
    );

    Backbone.history.navigate(this.pathname, { trigger: true });
});

Listening to the route event from your Backbone.Router you then restore scrollTop when it exists in history.state, or default to page top. To catch navigation happening via the back- and forward-buttons in the browser, Backbone.history should be set up to listen for popState events by setting { pushState: true } in the options to Backbone.history.start().

// Backbone.Routers trigger the route-event
// after the route-handler is finished
var router = new AppRouter(); // AppRouter extends from Backbone.Router

router.on("route", function () {
    // Inspect history state for a scrollTop property,
    // otherwise default to scrollTop=0
    var scrollTop = history.state && history.state.scrollTop || 0;

    $("html,body").scrollTop(scrollTop);
});

For those who need to see before they believe, take a look at the demo.

NB. The code examples are simplified to the extreme and shouldn't be treated as complete drop in code.

Shorts

Oct 21st 2013

Revisiting an old classic

11:02

Last weekend, I clocked in quite a few hours playing an old classic: Frontier: Elite II. What inspired me to dust off a 20 year old game, was a series of Frontier tutorial videos I stumbled upon. While waiting for the upcoming Elite: Dangerous to be released, I'll probably spend copious amounts of time exploring the vastness of space.

If the idea of being a space trader or rogue assassin tickles your fancy, but you're the kind of person who prefers more advanced graphics, you should check out Pioneer. It's an open source remake of Frontier with a very nice looking facelift.

If you, like me, prefer the original, a good source of information can be found at the Frontierverse website.

Aug 24th 2013

DigiPod wants to revive your old gear

22:57

DigiPod promises to deliver what Silicon couldn't. The sub full-frame sensor is a bit of a let-down, but the prospect of having all that film gear for digital photography is interesting nonetheless.

Shorts

Jun 27th 2013

How to turn your smartphone (nearly) useless in one simple step

17:16

I've owned a smartphone for a long time now. I purchased a Nokia N95 back in 2007 (in Finnish only, sorry), which I would consider my first smartphone. Albeit somewhat different from modern pocket computers, it did among other things have apps, a decent onboard camera, a gyroscope, a GPS-chip for pinpoint location services. Pretty much the most used features modern smartphones equip, although recent years' development have added improved usability into the mix.

One monolithic issue still remains though, which hasn't much changed since those early years; the minute you leave your home country, your phone becomes useless, save for the camera, and possibly the GPS if you have the luxury of offline maps.

Unless you're willing to endure the horror of a colossal phone bill from enabling roaming mobile data, you won't be using the routing feature in your maps app (unless you have an onboard address database, which I don't); you won't be looking up addresses for that shop you were looking for; you won't be updating social networks with your witty comments and/or stunning photographs. To top it all off, open wi-fi networks can be surprisingly hard to find, unless you happen to be in a busy area laden with cafés, restaurants or bars.

Not having an internet connection on a smartphone makes it about as useful as a wheel-less wheelchair: you can still sit comfortably, but you're not really getting anywhere.

Luckily, within the EU, there is a set rate ceiling of 0,70 euros/MB from July 1st 2013 (again in Finnish only, sorry), and a maximum charge of approximately 60 euros, after which your data connection will be terminated. Having a ceiling for data costs is an improvement, surely, but that will only give you a measly 85 MB, which is quite little considering the amount of data flowing in and out of handsets these days.

While waiting for better days for roaming data, do travellers a favour: open up your wi-fi network, even a fraction of your bandwidth is a great help.

Shorts

Meta

Pages

Search blog

Latest comments