Hacker News new | comments | show | ask | jobs | submit login
Show HN: jQuery.pin – a plugin for making stuff stick (github.com)
65 points by bobfunk 1464 days ago | hide | past | web | 36 comments | favorite

As a best-practices criticism, this is using a direct window scroll handler, which can be a bit of a performance nightmare. It's often better to use some sort of throttling to make sure your scroll handler only runs every X ms. The tradeoff there, of course, is that you get a slightly less buttery-smooth pinning experience... but in return your pages will still scroll nicely on non-zippy machines.

Resig wrote about this after it horribly mauled Twitter a few years back: http://ejohn.org/blog/learning-from-twitter/

For anyone wondering "why do we need jQuery plugins for simple things like this?", you may be interested in position: sticky. Here's an article: http://updates.html5rocks.com/2012/08/Stick-your-landings-po.... Worth noting that this hasn't actually been adopted as part of the spec, but it certainly would be a welcome addition in my opinion.

This plugin looks well-done, but I'm looking forward to a day when we don't need JavaScript to control layout like this.

This is good but there are some more mature solutions out there, bootstrap has a very basic 'affix' plugin built in. However I have found the waypoints plugin to be absolutely amazing and flexible for any sort of sticky stuff:


Waypoints is more mature and can do much more complex stuff, but as with my earlier response about affix, for our use-case of pinning an unpinning the descriptions of the screenshots in our gallery, Waypoints didn't really come with anything out of the box.

I built something like this about a year ago called sticky-panel. https://code.google.com/p/sticky-panel/ Mine only has a couple added features like before and after detach events and support for overflow divs.

Do you have a demo for it somewhere?

Could do with some smoothing and polishing. Jerks all over the place.

Also, what is with this new fashion of declaring functions as anonymous methods?

    var recalculateLimits = function () { 
       /* snip */
    var update = function () { recalculateLimits(); onScroll(); };
Have I missed a memo?

EDIT: I forgot to say apart from my moaning, does the job, good code, good job! And it's only jerky when you use the scroll button on a mouse.

I learned this method with the book JavaScript the Good Parts, though it was a while ago and I can't remember the specific reasoning behind the books' recommendation.

From the other commenter's SO link, I found this link to go more in depth into the differences of declaring functions, and it seems to come down to having stricter control on the order of events with no surprises.


And here's an example of one of the surprises you'll run into if you don't declare your functions in this way: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoistin...

I'm not a JS programmer, but I'd say that always using the function expressions (var a = function() {}) is bad. I understand that it's more useful when you intend to manage it as an object, or as part of a bigger object (the additional reasons your first link gives).

But about the hoisting problems... For me, the real problem is that you're declaring a function inside a function. Or using variables with the same name. That's a bad practice, it doesn't make sense. It should be avoided instead of using language constructs to work around it.

That's definitely not in javascript the good parts. It's a new thing and its spreading like some sort of horrible virus. It has quite the opposite effect that you're prescribing to it.

Your second link describes both variable hoisting, a real problem which causes serious problems, and function hoisting that has never been a problem as almost every other modern language behaves that way.

You don't seem to be a polyglot or you'd understand the problem immediately. Variable hoisting is just downright bizarre if you've worked in almost any other language, whereas function declarations can be anywhere in most languages and so when they are declared is almost completely irrelevant to a programmer.

Artificially assigning them to a variable so that suddenly function declaration order does matter is just downright weird. The 'normal' function declaration is better and clearer.

I'm probably not the best person to have a debate about this since I don't have a traditional CS background. I dabble in many different languages, but I'll never claim to be an expert in any.

To your point about this not being in the book JavaScript the Good Parts, I re-downloaded my purchase from Oreilly to double check, and throughout the book, all functions are declared as variables. Here's a screenshot from the second page of the "Functions" chapter, which is the first time a function declaration is introduced in the book: https://dl.dropbox.com/u/1517499/Screen%20Shot%202013-03-26%...

Edit: Just an edit to add that I quickly perused the pdf and couldn't pick out anywhere where he explained why he recommends this way. In any case, I'm always open to any arguments one way or the other.

You're quite right. Bizarre that it didn't even register. At least that explains why some people have picked up that habit.

Crockford himself seems to have abandoned the habit if you check his github code.

I don't think that's what he's addressing, though.

It's this:

var foo = function() { redeclaration(); }

that I believe he's referring to, unless I'm mistaken.

I don't believe so. It sounds like he prefers using function declations to function expressions. And this is incorrect according to most js gurus. For example:


From that link:

"b) Function Expressions are more versatile. A Function Declaration can only exist as a “statement” in isolation. All it can do is create an object variable parented by its current scope. In contrast a Function Expression (by definition) is part of a larger construct. If you want to create an anonymous function or assign a function to a prototype or as a property of some other object you need a Function Expression. Whenever you create a new function using a high order application such as curry or compose you are using a Function Expression. Function Expressions and Functional Programming are inseparable."

Also this link: http://kangax.github.com/nfe/

brings up these disadvantages to function declarations:

* can't conditionally declare functions with consistent results across browsers * function declarations cannot appear in blocks (technically), though many implementations allow this in practice

finally, i'd argue that function expressions encourage you to think of functions as the first class objects js intended them to be

He included far more code than was necessary, if that's the case. I don't see why the implementation of the function expression would be relevant if so. Clarity would help here.

Why would you want a function called "callback" polluting you global namespace?

What you suggest makes no sense in Javascript. Variable functions allow the developer to simulate namespacing in JS without polluting the global namespace.

This [0] is the only difference I am aware of. But I would love to hear someone talk about performance differences (if any).

[0]: http://stackoverflow.com/a/336868/712889

I actually got in an argument with someone on SO the other day who swore blind that the only was to declare a 'class' was using this pattern. Took a fiddle to shut him up.

I just don't get what it adds to your code apart from hiding simple function definitions in the visual trappings of a static helper object or closure. Javascript is already homogeneous enough without making it visually even more.

>> I just don't get what it adds to your code apart from hiding simple function definitions in the visual trappings of a static helper object or closure. Javascript is already homogeneous enough without making it visually even more.

What method do you use instead of the following, when creating namespaces?

var yourNamespace = {

    foo: function() {

    bar: function() {

Wait, I don't think that JavaScript is homogeneous, not in the least, for me it's really heterogeneous, I can look at 3 or 4 scripts developed by people of different skills and backgrounds and see it done in 3 or 4 completely different styles, visually and syntactically.

Did you messed up the wording over homogeneity?

I mean the syntax is homogeneous, I agree the styles in use today certainly aren't!

The one I mentioned above, you cannot conditionally create functions using function declarations.

From the discussion in one of the replies:

Named function expressions demystified http://kangax.github.com/nfe/

That's actually discussing totally different concepts with a couple of side mentions (the only related bit being in Function names in debuggers).

But at no point do the use this technique for declaring functions any where else.

Interestingly in that article they don't even entertain the possibility that someone would ever declare a javascript function that way. A mere 3 years ago.

How does this compare to say Bootstrap's affix plugin? I see that it supports a min-width property, but personally I'd rather deal with this myself via media queries (matchMedia API in JS) than have a limited option via the plugin.

The difference is being able to specify a containing element, so the pinned part gets unpinned once you scroll past the bottom of the container.

We first developed the plugin for the Webpop gallery page (http://www.webpop.com/gallery) to make the description next to each screenshot stick to the top while you were viewing that gallery entry.

Later we also used it for the pinned navigation in our documentation section to make sure it didn't stay fixed and overlapped the footer once you scroll down to the bottom of the page. As far as I know Bootstrap's affix doesn't really help you there.

This and all other solutions on this page doesn't work, when sticky block height is more than window height. Always showed the top of the block, but it should be scrolled to the bottom, when you are scrolling content, in other way to see the bottom is possible only in case when page scroll to the bottom or container where this sticky block is embedded is over.

Is there something like this that works properly in the mobile browser?

I have had reports that https://github.com/bigspotteddog/ScrollToFixed runs on mobile. Here are the confirmed combos:

- iPad 4 running iOS 6.0 (10A403) with dontCheckForPositionFixedSupport: true

- iPad 4 running iOS 6.0.1 (10A523)

- iPad 1 running iOS 5.1.1 (9B206) with dontCheckForPositionFixedSupport: true

- Nexus 7 running Android 4.2.1 with dontCheckForPositionFixedSupport: true

Unfortunately, I am mobile challenged so I cannot test these out for myself.

I am the author of ScrollToFixed, which has been out in the wild for a couple of years and does docking top, bottom, middle and still allows the fixed elements to move with the horizontal scroll, which is great for table headers.

I was thinking about posting it on HN when I got a break in the action. Haven't had a break in the action yet.


The Network tab in my inspector shows that the Neuton font family from Google fonts that you're having problems with is a whooping 649 Bytes. I'm OK with that...

every time this kind of plugin comes up, i link to this one from years ago https://github.com/terkel/jquery-floating-widget

Doesn't work on IE10

Pushed a fix - should work in IE10 as well now.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact