So you have some number, x, which you want to round to the nearest integer.
Easy, right?
x = Math.round(x);
Sure, but is this the fastest option? I think not.
x = x < 0 ? x - 0.5 >> 0 : x + 0.5 >> 0;
What the heck's going on here? >> is JavaScript's right shift operator.
It shifts a number's binary representation n bits to the right, where n
is the value to the right of the operator. Since n is 0 in this case, no
shifting will occur, although the resulting value will be an integer.
Note that this approach results in -82.5 being rounded to -83.
If, for some reason, your code calls Math.round() millions of times, it may
be worth investigating the bitwise approach to avoid the overhead of all those
function calls.
Stick to Math.round() the rest of the time, though, as it makes for much
clearer code. Never optimize prematurely.
Earlier I wrote some code which repeatedly calls a function which performs
a database query – often the same query. This encouraged me to explore
various ways to cache the results of function calls in both Python (to solve
my immediate problem) and JavaScript (because I find that language endlessly
fascinating).
I played around with Fibonacci, which is a well suited to the task: it
can be described in just a couple of lines of code yet benefits enormously
from caching due to its recursive nature.
JavaScript Fibonacci without caching
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 2) + fibonacci(n - 1);
}
I write a lot of Python. I also write a lot of JavaScript. As I switch between
the two (often several times in a day) I sometimes find myself trying to do
something in one using the syntax of the other. The most common example is
joining a list.
Often — as is the case above — the syntactical differences are minor, but
there are times when there's no direct translation.
MooTools, for example, adds the every method to the Array object.
This makes it possible to write some rather terse conditional statements.
var numbers = [87, 33, 21, 75];
if (numbers.every(function (n) { return n % 3 == 0; })) {
window.alert('The numbers are all divisible by 3.');
}
Python lists have no comparable method, so how would one write this in Python?
numbers = [87, 33, 21, 75]
if [n for n in numbers if n % 3 == 0] == numbers:
print 'The numbers are all divisible by 3.'
This approach involves using a list comprehension to create a list of numbers
which are divisible by 3, and comparing this list to numbers. If the lists
are equal, everything in numbers is divisible by 3.
Now for something a bit more challenging
Assume that we have a list of documents, and we want to know which of the
documents contain all the terms in a list of search terms.
Here, we could use the list comprehension approach as before.
# Python
terms = ['python', 'list', 'methods']
matches = []
for document in documents:
if [t for t in terms if document.body.find(t) != -1] == terms:
matches.append(document)
This is reasonably succinct, but not terribly efficient since each document is
checked for every search term. Given that we're not interested in documents
that lack even a single search term, it should be possible to rewrite this code
so that we don't waste time on lost causes.
It turns out that Python has just the thing for the job: in Python, a loop
statements may have an else clause!
terms = ['python', 'list', 'methods']
matches = []
for document in documents:
for term in terms:
if document.body.find(term) == -1:
break
else: # every term was found
matches.append(document)
Loop statements may have an else clause; it is executed when the
loop terminates through exhaustion of the list (with for) or when
the condition becomes false (with while), but not when the loop is
terminated by a break statement.
I'm looking forward to finding more good spots to make use of else
clauses with my Python loops. :D
Over the past few months I've reached a startling realization: JavaScript
is a tremendously capable language.
The reason that it took me so long to discover this is that the playing field
has never been fair. On the one hand I've been writing application code for
the server, a stable, predictable environment. On the other hand I've been
adding interactivity on the client's side, dealing with inconsistencies on
multiple fronts, not least of which is the DOM API.
Comparing Python and JavaScript, for example, by using the former to quickly
put together a website using the excellent Django framework while using the
latter to add drag and drop functionality is to compare apples and oranges.
Actually, it's more like comparing apples to root canals.
I've spent the afternoon creating a custom scrollbar for a products viewer
which utilizes CSS transitions, reflections, and other goodness.
Simple arithmetic dictates how long to make the scrollbar and where to position
it, but I could not get my theoretical calculations to play out in the browser.
It turns out that I'd been calling the wrong MooTools method. I'd been doing…
element.setStyle('left', offset);
rather than…
element.setPosition({ x: offset });
Frustratingly, setStyle('left', offset)appeared to work, but its behaviour
was unpredictable. I'm still confused by this, but at least I'm no longer
stuck.
Comment forms that don't provide previews — or at least an indication of
how comments are processed — really annoy me. If I decide to leave a comment
I take care to avoid spelling mistakes and grammatical errors. It's quite
upsetting, then, to see my code snippet completely mangled and my carefully
typed links displayed in plain text (<a href="…).
Despite my appreciation of the preview, not one of my sites provided this
service until a few hours ago. Now that I've migrated from WordPress to
Mango I'm able to spend some time working on front-end code. My first two
challenges were localizing dates and times, and integrating wmd.
Getting wmd working turned out to be extremely easy, but I was not content with
a live preview of the comment only. No, I wanted the preview to resemble as
closely as possible the published result, which meant updating the preview area
in response to changes to "name", "e-mail", and "website" as well as to changes
to the comment itself.
Early this year I wrote a post titled
Auto-populating input fields with Prototype. Looking at the code now,
I realize that it's not very pretty. I'm rewriting this site's JavaScript
in MooTools, and the new code is quite a bit more elegant.
// provide input hints
window.addEvent('domready', function () {
$$('input[placeholder]').addEvents({
focus: function () {
if (this.hasClass('placeholder')) {
this.removeClass('placeholder').set('value', '');
}
},
blur: function () {
if (this.get('value') === '') {
this.addClass('placeholder').set('value', this.get('placeholder'));
}
}
}).fireEvent('blur');
});
I really appreciate the fact that MooTools provides addEvents in addition
to addEvent. As a result, the code above is clearer than a well-written
Prototype equivalent.
Regular expressions are powerful, useful, and -- in my opinion -- lots of
fun! Thanks to the prevalence of Twitter, every web developer will be exposed
to regex sooner or later: before outputting tweets in HTML, Twitter names and
hyperlinks must be wrapped in anchor tags.
Matching @names
Here's the gist: a match will begin with "@" and the at sign must be followed
by one or more word (letter / number / underscore) characters. The @name must
either appear at the beginning of the tweet or be preceded by a space. This
prevents the regular expression from matching "@example" in "me@example.com".
[…] Moments ago I used JSLint for the first time; I plan to use it frequently
from this point forward. I have one question, though, concerning the acceptability of
extra commas. Consider the following code snippet:
var ninja = {
name: 'Hattori Hanzou Masashige',
shuriken: 5,
attack: function () {
if (ninja.shuriken) {
ninja.shuriken -= 1;
window.alert('Hai-Ya!');
}
},
};
JSLint returns an extra comma error for the unnecessary comma preceding the closing
brace. I would argue, though, that this in not an error. As far as I'm aware, this
comma will not cause problems.
In fact, quite the opposite is true. If one were to insert an additional property or
method after attack one would not need to remember to first add a comma. In Django
it's considered best practice to include a comma after every item (including the last)
in a one item per line collection for this very reason.
I thought I'd give you my two cents, anyway. :)
Regards,
David Chambers
On ,
Douglas Crockford wrote:
Your awareness is incorrect. Have you tested on IE6?
Generally speaking browsers rerender elements as required – in response to DOM
changes effected via JavaScript, for instance. There are times, though, when
the browser (Internet Explorer, I'm looking at you!) needs a gentle nudge.
Element.addMethods({
redraw: function (element) {
element = $(element);
var n = document.createTextNode(' ');
element.appendChild(n);
(function () { n.parentNode.removeChild(n); }).defer();
return element;
}
});
The post's first comment includes an alternative approach:
element.className = element.className;
I gather that there are situations in which this simple solution fails — it's
no silver bullet — but it fixed a problem I encountered in IE8 earlier this
evening so I'm pleased to have discovered it!
A reasonably common task is to determine whether a particular statement
evaluates as true for every item in a collection. Take list,
for example, an Array containing several numbers:
var list = [4, -1, 3, 2, 5];
One might wish to determine whether all the numbers in list are
positive. The required logic is as follows:
assume that all the numbers in list are positive, then…
loop through list until the assumption is proven to be false,
or until all items in list have been tested
In plain JavaScript, this can be achieved using a for loop…
var allPositive = true;
for (var i = 0; i < list.length; i++) {
if (list[i] <= 0) {
allPositive = false;
break;
}
}
… or a while loop (which is slightly more efficient).
var allPositive = true, i = list.length;
while (i--) {
if (list[i] <= 0) {
allPositive = false;
break;
}
}
Seriously, though, who is writing vanilla JavaScript in 2010? Everyone
and their grandmothers are using JavaScript frameworks these days, and there
are plenty of good ones out there. I recently made the switch to MooTools
from Prototype, after deciding that while jQuery is fantastic, the
MooTools philosophy is more to my liking.
var allPositive = true;
list.each(function (item) {
if (item <= 0) {
allPositive = false;
}
});
While this gets the job done, it's suboptimal for two reasons: the positiveness
of every item is evaluated, which will often not be necessary; and, well,
it ain't pretty. ;)
Enter every
As is so often the case in programming, if something seems fiddly and difficult
there's probably a better tool for the job. In this case the Array object's
every method is the perfect tool for the job.
I've recently become interested in optimizing sites for the iPhone and
iPod touch. While nothing beats testing on the device itself, I often find it
quicker to test changes on my Mac. Changing the user agent string is a piece
of cake in Safari (Develop > User Agent > Mobile Safari) but what about
adjusting the browser window's dimensions to match those of the iPhone?
I've created two bookmarklets to allow the current page to be loaded in an
iPhone-sized window with a single click:
Many of those who write JavaScript do not come from programming backgrounds
(while I've written plenty of PHP, Python, and JavaScript, I don't have much
experience with "real" programming languages*). As a result, a
significant portion of JavaScript coders do not think of variables as pointers
to memory addresses. This leads to confusion in cases such as this:
var fruits = ['orange', 'lime'];
var colours = fruits; // naïve attempt to duplicate array
colours.append('yellow');
One might be surprised to learn that fruits now contains not just "orange"
and "lime" but also "yellow". Oops! Here's how it went wrong:
var fruits = ['orange', 'lime'];
// fruits points to array containing "orange" and "lime"
var colours = fruits;
// colours now points to that same array!
How, then, does one create a copy of the original array? Slice!
Yesterday I wrote a simple class which auto-populates
input fields, and thought it worth sharing. I was originally
inspired to write this code by Roger Johansson's post titled
Autopopulating text input fields with JavaScript. While
I approached the problem from a slightly different angle,
I made sure to avoid the pitfalls Roger mentions.
|| date: 9 June 2010
|| time: 11:31pm
||
|| I've written an update to this article for those interested in
|| auto-populating input fields with MooTools.
||
|| [2]: /autopopulating-input-fields-with-mootools/
Nothing new here. I've combined Prototype 1.6.1 and the various
files that make up script.aculo.us 1.8.3 (except unittest.js) into one
file, which I've minified using the YUI Compressor. Further compression
has been achieved by gzipping the minified file. All three versions are
available for download:
This prevents caching issues that might otherwise arise upon updating to a
newer version of prototype+scriptaculous (I'll update the three files — and
this post — each time a new version of Prototype is released).
I began this post three months ago, got stuck, and put it in the too hard
basket. I wanted to devise a workable solution to my stumbling block before
publishing this information. I'm getting ahead of myself, though. First, the
background.
As I began writing this post, I had just completed a redesign of this
site. The new design removed unnecessary distractions to allow readers
to focus on the clearly presented content. I moved site navigation
from the sidebar (which I axed altogether) to the header. I decided to
fix the header in place so that the navigation and search form would
always be visible. This required very little effort, but overcoming the
problem posed by fixed-position headers took a great deal of trial
and error. To save others from going through this tortuous process I'll
describe my various approaches, and list the benefits and drawbacks
of each.
In my post titled Captions over images I advocate the use of
definition lists for captioning images. Earlier today I was asked
whether this meaningful markup could be used in conjunction with an
"image slider" such as Easy Slider 1.5.
I had a look at the Easy Slider source code and decided to write my own
image slider using Prototype rather than hacking someone else's code to
pieces. It's a proof of concept rather than a full-blown "plugin", but
it demonstrates that such functionality is achievable using elegant,
meaningful markup.
This is my response to Chris Coyier's screencast titled
jQuery Part 3 – Image Title Plugin which I watched a couple of days ago.
Something didn't sit right with me at the time, and I've now worked out what
it was: JavaScript is not required!
I'll present a JavaScript-free approach for displaying captions over images
that uses truly meaningful markup.
It's no secret – I love Coda! It's a pleasure to use. It looks so
damn good. When I started using SyntaxHighlighter I set out to create
a Coda theme. Thankfully, the good folks at Panic had done the ground work
for me. All I had to do was create a style sheet that would make my code
snippets look as sexy online as they do in my text editor.
This is a JavaScript function for Photoshop which saves the active document
as a 24-bit PNG file. It is equivalent to manually selecting File > Save for
Web & Devices… which means that the file size of the resulting PNG will be
smaller than would be the case using PNGSaveOptions().
function saveForWebPNG(outputFolderStr, filename)
{
var opts, file;
opts = new ExportOptionsSaveForWeb();
opts.format = SaveDocumentType.PNG;
opts.PNG8 = false;
opts.quality = 100;
if (filename.length > 27) {
file = new File(outputFolderStr + "/temp.png");
activeDocument.exportDocument(file, ExportType.SAVEFORWEB, opts);
file.rename(filename + ".png");
}
else {
file = new File(outputFolderStr + "/" + filename + ".png");
activeDocument.exportDocument(file, ExportType.SAVEFORWEB, opts);
}
}
Photoshop on Mac limits the length of a File object's file name to
31 characters. Credit for the rename workaround should go to Mark Walsh
who posted the solution on the Adobe forums in a thread titled
Save for web filename problems.
JavaScript does not have associative arrays. (This will be old news
to many.)
Confusion arises from the fact that array syntax in JavaScript is very
similar to array syntax in PHP, a language that does have associative
arrays. Additionally, any object in JavaScript can be treated as an
associative array. This means that if one creates a JavaScript Array
object and proceeds to use PHP's associative array syntax in an attempt
to add items to it, one will succeed in assigning it attribute–value
pairs. The object in question need not be an Array for this to work,
though, so for the sake of clarity using a vanilla Object is advisable.
SyntaxHighlighter is a fully functional self-contained code syntax
highlighter developed in JavaScript (as stated on its wiki). One of its
deficiencies is that it retrieves all its brushes each time a page is
loaded, despite the fact that in many cases only one or two (or none)
are required.
Currently, Prototype is my JavaScript framework of choice (although I'm
really looking forward to trying jQuery). I have used Prototype to create
a brush loader for SyntaxHighlighter, which retrieves brushes on demand
to reduce page loading times (in certain circumstances).
|| date: 27 June 2009
|| time: 6:21am
||
|| I have completely rewritten the code so that it no longer requires
|| empty functions inside the brush files to act as indicators of readiness.
|| Instead, the required brushes are retrieved in a daisy chain. This is both
|| more elegant and more reliable. Additionally, style sheets are now also
|| retrieved on demand.
Alex Gorbatchev's SyntaxHighlighter is a well-written bundle which
enables syntax highlighting of code via JavaScript. More than twenty
languages are supported "out of the box", and brushes (JavaScript files
containing language-specific regular expressions) can be created to
support additional languages.
Unfortunately, however, several of the brushes that come bundled with
SyntaxHighlighter are far from perfect. Have a look at the bundled PHP
brush in action below.
I've been using Alex Gorbatchev's SyntaxHighlighter to syntactically
display code of various languages for several months now. When I decided
to post an AppleScript snippet, however, I realised that I was out of luck.
SyntaxHighlighter does not include an AppleScript "brush", and a quick flick
through the SyntaxHighlighter forums did not bring me any joy.
How hard could it be to write a brush for AppleScript?, I wondered. The
handy guide to developing a custom brush got me started, and I was soon
busy trying to encapsulate AppleScript's syntax -- along with its keywords
and countless words and phrases with special meanings -- into a handful of
regular expressions.