EDIT: Sadly, although not entirely surprisingly, this doesn’t appear to work any more. Facebook is constantly changing the layout and content of their various pages, and I have no real intention to keep up with them. However the code may be useful for someone else to modify at any point in time to work on the current version. Sorry!
This evening I had that not-uncommon need to track down some dusty old Facebook comments from a couple of years ago. Naturally, Facebook makes it difficult to see anything more than a week old, but if you keep clicking “Older Posts” at the bottom of your (or a friend’s) Wall for long enough, you can see all posts back to the beginning of time.
This is kind of nice, but very tedious. Surely there’s a way to automate this process? I’ve seen numerous attempts, but many are either too complex for such a simple task (such as the sprawling Social Fixer browser extension), or too simple for the ever-changing complexities of Facebook. I decided to take a couple of pointers and put my new-found jQuery skills to a quick test. The result: FBExpand, a simple tool for a simple purpose.
The code is up on Bitbucket for inspection, but to put it to work right away it’s much easier to use this bookmarklet: FBExpand. Drag that link to your bookmarks bar, and simply click it when you want to expand some Facebook history (e.g. when viewing your Wall). Too easy!
The code
(function(){ // The text in the link you wish to automatically expand. var expandText = "Older Posts"; // Timer delay (ms) between 'clicks'. Set to roughly the time it takes to load // the next link text. May need to increase value for slower connections. // Too short may freeze the script, however too long will waste time. var delay = 1500;
These couple of lines allow for some minimal customisability. The script locates the link button based on the text within it, chosen by the expandText
variable. This strikes me as more future-proof against Facebook’s endless interface changes than an otherwise more precise approach of drilling down the DOM or picking out element IDs and classes. The delay
variable is more or less explained by its comments.
/* Reduced from Karl Swedberg's jQuerify bookmarklet script at: http://www.learningjquery.com/2009/04/better-stronger-safer-jquerify-bookmarklet/ */ // Ensure jQuery is available as $jq (function(){ if(typeof jQuery!='undefined'){$jq=jQuery; return;} var head=document.getElementsByTagName('head')[0],done=false; var script=document.createElement('script'); script.src='http://code.jquery.com/jquery-latest.min.js'; script.onload=script.onreadystatechange=function(){ if(!done&&(!this.readyState||this.readyState in ['loaded','complete'])) { $jq=jQuery.noConflict(); script.onload=script.onreadystatechange=null; head.removeChild(script);done=true; } }; head.appendChild(script); })();
This block is simply Karl Swedberg’s jQuerify script reduced to its bare bones (i.e. removing the visual feedback). It ensures that the jQuery library is loaded and bound to the variable $jq
before proceeding. Read his post for an explanation; it’s about the third version, and it’s quite neat.
// Keep clicking the links until there's none left var loop = setInterval(function() { var a = $jq('a:contains("'+expandText+'")'); if(a.length) eval(a.attr('onclick').split('return')[0]); else {clearInterval(loop); console.log("All posts expanded.");} }, delay); })();
Here’s my stuff – it looks awfully straightforward after all that. Essentially, it follows a few simple steps, outlined below. Since the code is wrapped in a setInterval()
function call, it is called again every delay
milliseconds. This allows Facebook a little time to load the next batch of posts before performing another click.
- Find the expand link based on the text contained within it using a jQuery DOM selection.
- If the link exists, grab its onclick code and execute it, effectively emulating a user’s mouse click. For some reason simply calling
.click()
on the jQuery object wasn’t working, so this was my workaround. - If the link doesn’t exist, there’s nothing to expand, so the script ends, putting a stop to the repetitive interval execution and printing a simple debug message to the browser’s console.
Thoughts
This little exploration has done little to change my perception of JavaScript as a rather hacky approach to software development. Of course, any language can only be as elegant as the task (and developer) allows, and if you’re trying to do hacky things like this, then JS/jQ are fantastic. As far as modern web UI design goes however, I’m still looking forward to spending some quality time learning Dojo in the future. Coupled with Backbone.js, it looks like a very powerful tool for any serious web development.
Naturally, such a tiny script should be very possible without any jQuery-like library. In retrospect, the only thing I use it for is to select the expand link node. Perhaps I’ll rewrite it tomorrow to do that in standard JS and cut the script in half. It’s all good practice, in any case.
Finally, my efforts went somewhat unrewarded, since I didn’t find the exact post I was looking for. I realised too late that it was a comment on an activity (Liking a Facebook page) rather than on a post. Since activities aren’t really shown on one’s Wall the same way any more, neither that Like or its comments could be found. If anyone knows how I might be able to locate something so specific, please let me know! I’ll own you one.