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.
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?
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.
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.
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 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.
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...
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.
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'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.
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:
"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."
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.
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.
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.
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.
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.
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.
36 comments
[ 3.8 ms ] story [ 80.8 ms ] threadWe 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.
Also, what is with this new fashion of declaring functions as anonymous methods?
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.
[0]: http://stackoverflow.com/a/336868/712889
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 = {
};Did you messed up the wording over homogeneity?
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.
http://javascriptweblog.wordpress.com/2010/07/06/function-de...
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...
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.
Named function expressions demystified http://kangax.github.com/nfe/
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.
http://imakewebthings.com/jquery-waypoints/
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.
It's this:
var foo = function() { redeclaration(); }
that I believe he's referring to, unless I'm mistaken.
http://javascriptweblog.wordpress.com/2010/07/06/function-de...
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
Crockford himself seems to have abandoned the habit if you check his github code.
This plugin looks well-done, but I'm looking forward to a day when we don't need JavaScript to control layout like this.
What you suggest makes no sense in Javascript. Variable functions allow the developer to simulate namespacing in JS without polluting the global namespace.
- 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 was thinking about posting it on HN when I got a break in the action. Haven't had a break in the action yet.
Resig wrote about this after it horribly mauled Twitter a few years back: http://ejohn.org/blog/learning-from-twitter/