Javascript Notebook

These are code snippets and rambling musings about Javascript.

Bookmarklet to Mass-Unfollow Twitter Users

I almost wrote a page for this, but it turns out a bookmarklet is good enough:

javascript:$('.js-follow-btn').click();undefined;

Make a bookmark, and set that as the URL. Then load up the page of people you're following. Scroll down a bit so more of the users get loaded. Then click the bookmarklet. In a second, all the users will be unfollowed. Reload and start again.

Function-Generating Functions in Javascript

I wrote this before I practiced with the module pattern and with adding methods to prototypes. So this article doesn't explain a best practice. Still, it's a pretty good pattern. See also the Javascript Patterns book.

JS has closures, and with closures, you can create functions that return functions as values. Erm. So what? Well, the closure is not just a function, but also its "environment". I think the term in JS is "local variables". So the function carries with it, a bunch of its local variables.

This means you can create a function that "remembers" some values you've passed to it. Here's an example:

foo = function (x) { return function (y) { return x + y; } }

To use it, you do this:

addone = foo(1);
addten = foo(10);

Now, addone(5) returns 6. addten(6) returns 16.

If that doesn't make sense, look at the code again. The body of foo is "return function (y) { return x + y; }".

Well, x, in this case, is a local variable that you passed into foo().

So the code of addone is really something like this: "function addone(y) { var x = 1; return x + y; }".

You may need to re-read the above.

The point here is that the function creates another function, and that function is slightly tailored to do something. Now, that might seem pointless, but it's not. It's a lot like objects and methods, except instead of creating a lot of objects, you now can create a lot of functions that contain some data.

If you think about it, the jQuery and current JS style of programming involves creating a lot of anonymous functions and attaching them as handlers onto the DOM objects. A function-making function is really handy, because you can go through a DOM and attach a unique handler function to each object.

Here's part of a function I'm working on. It might not work:

SW.map.listFormatterMaker = function (prefix) {
  return function (d) {
    $.template('MainInjectList', 
      ' ${name} ${city}, ${address}');
    document.getElementById( prefix+'-list' ).innerHTML = '';
    document.getElementById( prefix+'-list2' ).innerHTML = '';
    a = d.slice(0,5);
    b = d.slice(5,10);
    a.forEach(SW.listInserter( prefix+'-list')); // this is another function-making function
    b.forEach(SW.listInserter( prefix+'-list2'));  // ditto
  }
}

It's a little long, but it's a function that returns a "listFormatter". A "listFormatter" is a function that formats some data that's passed do it.

It takes a 'prefix' parameter. The HTML includes two UL elements that have IDs of 'map-list' and 'map-list2'. I'm using a naming convention, and the prefix is "map".

When SW.map.listFormatterMaker('map') is called, it returns a function. That function, when passed some data, d, it'll format and insert the data into my page.

Before inserting the data, it splits the array into two (for two columns), and then inserts into -list and -list2, separately. To do the insertion, it uses forEach and another function-making function called listInserter().

So, if I want to re-use this code, I could create some HTML with IDs of 'map2-list' and 'map2-list2' and pass 'map2' as the prefix. Then, calling SW.map.listFormatterMaker('map2'), will make a different function that will do the same thing for a different area of my page.

It's used like this:

$.getJSON('foo.php',{arg:1},SW.map.listFormatterMaker('map'));
$.getJSON('bar.php',{arg:1},SW.map.listFormatterMaker('map2'));

So that's 2 function calls that are visible to the user, but the result is that four different areas of the page get updated with data. Each area is updated by anonymous functions.

You might be wondering if this can be done without this function-making-function business. I think it can, but it would be a lot more code. You would have to write a customized data handler for each call. With this style of programming, you avoid that.

Also, it's not just useful for specifying a selector. You can also pass it functions, so it's possible to create functions that have different behaviors depending on the functions passed into the function-maker.

Generate a Page of Random Passwords with Javascript

The attached HTML page is a password generator that creates a page of random 10-character passwords. It helps you manage one password per website, so a password leaked for one site doesn't get used on other sites. To use it, click and view the file.

You can also download it and use it - it's all done with Javascript so there's nothing that requires the server.

To use it, just keep the printed page in a safe place. Make a copy and store it in a fireproof safe or safe deposit box. As you use each password, make a note of the site. You may not want to use the full site URL. It doesn't matter. You might even try to obfuscate the site name or use an abbreviation. You have three blank columns so you can put in some fake data in there to add chaff, which is junk data meant to mislead someone who gets this paper.

You can also do tricks, like ignore one letter in the password. So you have 9 character passwords instead of 10 character passwords. If the password list is lost or stolen, the guesser would have to guess which character is being dropped from the actual password.

You can transform: perhaps the first character is reduced by 1, so B becomes A, 8 becomes 7, etc. You can transpose - the first two characters can be swapped, so 1} becomes }1.

Every year or so, you can change your passwords and clean up your lists (doing things like alphabetizing them. You might keep the old lists as "decoys". Repeated failed logons will cause some sites to lock out the account. This is another kind of chaffing, where you "fluff up the haystack" and hide your needle in it.

The real password and url is discoverable, but it should be hard for someone to figure out.

See also: http://en.wikipedia.org/wiki/Password_strength#Creating_and_handling_passwords.

AttachmentSize
randompasslist.html1.22 KB

Hiding Email Addresses from Spiders and Spammers

Here's a bit of PHP code that emits javascript. The javascript emits an email link, but coded in Javascript, so that most spiders won't be able to get your email address for spamming.


<?php
function printEmailAddress( $email )
{
$parts = explode( '@', $email );
echo ' var d = document;';
echo 'd.write("");';
echo 'd.write("'.$parts[0].'");';
echo 'd.write("@");';
echo 'd.write("'.$parts[1].'");';
echo 'd.write("
");';
}

printEmailAddress("fake@mail.com");
?>

Interstitial Ad in jQuery

Normally, you should use canned Javascript or canned PHP modules to implement web features, but sometimes, that can suck. Typically, these products, if they're popular, start to suffer from feature bloat. Such was the case with some code for "interstitials", which are those ads that pop up on some web pages, interrupting your reading. Popups have been around a long time, and the drop-in code is just really huge.

Nowadays, you can assume that you'll have at least one JS library installed on the site. I started with Dojo, and now use jQuery. There's also Scriptaculous on top of Prototype (I'm kinda iffy about those), and Mootools.

So you can immediately cut code size by using the library, which is large, but can be cached -- if you link to it from one of the CDNs like Google -- and is reused for other things. Then, you can start looking at libraries.

The best interstitial library seems to be Shadowbox.js. It just looks nice.

Of course, sometimes, you just want to make your own, and you need special behaviors. In my case, I needed a form that integrates with an external site, not a thumbnail that expands, so Shadowbox wasn't a great fit. I just coded it by hand, and learned some more jQuery and CSS. To top it off, the code is a little smaller.

The interstitial ad feature is attached. If you need more explanation, please ask in a comment, and I'll do my best to accomodate.

May-Jun 2012: 80, pagerank 1 for interstitial jquery ad

AttachmentSize
inter.zip30.05 KB

Javascript Delayed Hiding of an Element, Delayed Function Calls in Different Contexts

So I'm working on a small "speech bubble" library, and needed to delay hiding of the bubble. It's not that it was required, but it was a pain in the butt figuring out how to arrange the event handlers on the different elements so that you don't end up with a situation where you get a flickering bubble because you hide the bubble, and that fires a mouseover event that, in turn, displays the bubble again. That fires a mouseout event that causes the bubble to be hidden.

The usual right way to fix this is to detect the mouse moving into the area around the hotspot, and when it does that, hide it. My cheap fix is to just delay the hiding, and if the mouse happens to enter another element that requires the bubble to be displayed, the handler for this other element can cancel the hide.

A delay is also "nice" because it also gives the user a chance to roll back if they overshoot a target a little bit.

Here's the code fragment to implement a delay:

  var hide = function () {
    this.bubble.style.display = 'none';
  }
  var delayedHide = function() {
    (function (x) {
      x.hideInProgress = setTimeout(function () {x.hide()},250);
    })(this);
  }
  var cancelHide = function() {
    clearTimeout(this.hideInProgress);
  }

The one really weird part is in delayedHide. What this does is construct a function that will call setTimeout(), then immediately call it. That calls setTimeout(), which registers the timeout handler to fire off in 1/4 second. Why not just call it like this?

this.hideInProgress = setTimeout(function () {this.hide()}, 250);

Well, the problem is that "this" changes between the two calls. When it's called from the bubble object (i.e. b.delayedHide() ), "this" is set to the object. When the timeout happens and the function's called by the system, I think "this" is set to window. Anyway, it's a different "this". "this" may not even exist. We're screwed.

So what we do, instead, is use a function to create a closure. A closure holds is local variables. So, what's happening is that (function(x) { ... })(this) is setting the local variable x to = this. Then, when function(){x.hide()} is created, it also carries the local variable x within the closure. That's because the closure contains the local variables in the scope in which is was defined.

After the call, the outer function wrapper is thrown away, but the inner one is stored away in window, ready to be called in 250 milliseconds.

Javascript Functions and Closures for Private Properties

A JavaScript Module Pattern is a fantastic example of how to use closures.

Javascript Closures has more detailed information.

Douglas Crockford brought the style over to JS, and his site has a lot of important articles about Javascript hacking (as a functional language).

A good description of closures is part of Blocks and Closures in Ruby an interview with Matz.

This video, Advanced Topics In Programming Languages: Closures For Java with Neal Gafter has a pretty detailed explanation about implementing closures in Java.

Last but not least, PHP 5.3 will have closures. What's new in PHP by John Mertic at IBM developerworks details the feature. The PHP RFC also has good examples.

AttachmentSize
closure.png12.65 KB

Javascript Functions and Functors

Joel on Software has a good article that explains functors, the purpose of passing functions as paramters, and leads into an explanation of map/reduce and parallel computing. These ideas are explained in Javascript, but also apply to Lisp, Scheme, and Perl (see the Mark Jason Dominus book). All these languages are functional programming languages, where functions are objects (or objects are functions).

(Add examples of functional programming here.)

Unfortunately, PHP, the other language covered here, has only half-baked functional programming. See the Function Handling Functions section of the manual.

Learning Javascript via the Read Eval Print Loop (REPL)

All the tutorials out there teach JS by having the user write a file, and load it into the browser. That's unnecessary work, if what you're really doing is learning the language syntax and are not interested in the web browser environment.

Most contemporary scripting languages have a Read Eval Print Loop (REPL), which some might call a "shell", or "console", or "interactive debugging", or "interactive toplevel", or "interactive mode". It's a prompt at which you type code, and the interpreter runs your code, and prints an output.

There are a few different REPLs for JS. The main one is in the error console, at the bottom. It's a command line. You can type anything into there, and it'll be evaluated.

In Firebug, there's a red button in the right side of the console's command line. If you press it, you'll get a small text editor where you can enter more complex expressions or even complete programs. To execute, press Control-Enter, or click "Run".

If you're on a Unix system, you can install node.js. On Ubuntu Linux, it's the "nodejs" package. The "nodejs" command starts a REPL for JavaScript.

Password Quality Evaluator

This is an up-and-coming feature on some sites. It measures the quality of a password, and gives the user immediate feedback about how good it is. The JavaScript below does that. It calculates the score by grouping the keyboard into uppercase, lowercase, punctuation, and numbers. You get points for length, for diversity in using keys from different groups, for switching groups often, and extra for using punctuation. The HTML part was intended for creating an .htaccess password. Here's a demo:
Password
Quality:

Resize YouTube Video (works with Vimeo and most sites)

This is a script to resize youtube video embed codes. It also works with other site. The youtube video is scaled proportionately. It should work with other video sites like Revver, Vimeo, LiveLeak, and even non-video embed codes.
Paste your code here:


Resize to this dimension (fill one):
Width:  
Height:
Get your new code here:
Return to: How to Resize a YouTube Video for Your Website on Associated Content. Return to: How to Resize a YouTube Video and Have it Look Right on eHow.

SelectAdd - A Checkbox Alternative

Checkboxes work well if you're dealing with a few choices, but stop working so well when there are many options, and only a few are selected. SelectAdd is some code that will display a CSS/JS/DHTML widget that makes it look like you're adding selections to a list.

This is just a demo script. It doesn't include any integration with a database backend.

AttachmentSize
selectadd.zip2.89 KB

Time Sheet Calculator

This script turned into the Multiple Time Sheets program. It's a calculator for time intervals in javascript.

Javascript Timesheet Calculator

This page reads your timesheet, which you paste in below, and adds up your hours. It's designed to work with somewhat organized data, in a format that I've used for years.

Do not type your timesheet into this page. You will lose your data! Use something like "Stickies" or some other notetaker, or Notepad, instead. Copy your data into this page, and use it as a calculator and timesheet formatter.

Total:        

A few caveats about the data format.

A little bit about this script.

It's written in Javascript, and requires a Netscape 4 or later browser that supports regular expressions. It's pretty much all about regular expressions. There's no PHP or Perl or anything like that involved. The script was written by John Kawakami and is in the public domain.

If you're interested in regexs, check out a refcard at Visibone. I used that page to make this page. (The cards are a good cheap gift for your local webhead.)

Using strings to create functions

One of the less-used features is the Function() object, which can turn a string of Javascript code into a function. This is an example of how it can be useful.

I recently hit an annoyance with the Android browser. Around version 3 and 4 of Android, the browser stopped supporting the JS history.pushState() and history.replaceState() methods, basically killing my LA IMC JS app.

Just to verify, I wrote the following to test the existence of those objects:

<script>
if (history) {
  document.write("history supported<br />");
}
if (history.back) {
  document.write("history.back supported<br />");
} else {
  document.write("history.back not supported<br />");
}
if (history.state) {
  document.write("history.state supported<br />");
} else {
  document.write("history.state not supported<br />");
}
if (history.pushState) {
  document.write("history.pushState supported<br />");
} else {
  document.write("history.pushState not supported<br />");
}
if (history.replaceState) {
  document.write("history.replaceState supported<br />");
} else {
  document.write("history.replaceState not supported<br />");
}

Yup. My inexpensive Android tablet with the 4.0.x OS didn't support them. Since the company wasn't releasing updates, it would never support them. What a pain. Also, since hundreds of thousands of devices out there lack this support, web apps will have to detect and work around the problem. "Thank you Google."

Anyway, all that code was long and a pain to edit, so I thought there must be a better way, and there was. You can use Function() to create new functions, like this:

apiname = "history.replaceState";
new Function( "if ("+apiname+") { document.write('"+apiname+" supported<br />'); } else { document.write('"+apiname+" <b>not</b> supported<br />'); }" )();

What Function() does is read the string, parse it as code, and then create a function object from it. Because it's a string, we can construct it using code, which we did, by inserting apiname into the code.

The () after the function causes the new function object to execute immediately. If you ignore the string, it looks like this: new Function("...")(); That makes a new function object, then calls it.

Expanding on that example, you can replace the first example with this:

apinames = ["history","history.back","history.state","history.pushState","history.replaceState"];
for( i=0; i < apinames.length; i++ ) {
  apiname = apinames[i];
  new Function( "if ("+apiname+") { document.write('"+apiname+" supported<br />'); } else { document.write('"+apiname+" <b>not</b> supported<br />'); }" )();
}

If you prefer the Array.forEach() style:

apinames = ["history","history.back","history.state","history.pushState","history.replaceState"];
apinames.forEach( function() {
  new Function( "if ("+apiname+") { document.write('"+apiname+" supported<br />'); } else { document.write('"+apiname+" <b>not</b> supported<br />'); }" )();
} );

Caveat: note that the Function constructor does NOT create closures. The functions are created in the global namespace. This can be good - as closures are slow and use a bit of memory. Closures keep references to their calling environment and have access to local variables in the context where the closure was defined.