Showing posts with label html. Show all posts
Showing posts with label html. Show all posts

Wednesday, 30 November 2011

The true story on return false

In JavaScript event handlers, you'll frequently see return false; at the end. Why? What does it do? The answer is: It depends. Before we get into the details, there are basically two things it could be doing:

  1. Preventing the default action of the event, such as when you click a link and the browser follows it.
  2. Stopping propagation of the event to ancestor elements.

So which does return false do? Just one, neither, or both:

  • DOM0 handlers: In an old-style DOM0 handler, hooked up via an attribute like this:
    <div onclick="return functionName();">
    ...it prevents the default action but doesn't stop propagation. Note that you need that return in the attribute. Try it here.
  • DOM0 handlers (again): The same is true of an old-style DOM0 handler hooked up via the reflected property for the attribute, like this:
    document.getElementById("someId").onclick = functionName;
    Try it here. As before, return false; prevents the default action but doesn't stop propagation.
  • DOM2 handlers: In a proper DOM2 handler hooked up via addEventListener, like this:
    document.getElementById("someId").addEventListener("click", functionName, false);
    ...return false does absolutely nothing. Instead, use the preventDefault and stopPropagation functions on the Event object your handler receives as an argument. Try it here (be sure to use a non-Microsoft browser, or use IE9 or higher).
  • Microsoft DOM2-ish handlers: In a DOM2-ish handler hooked up with Microsoft's attachEvent function, like this:
    document.getElementById("someId").attachEvent("onclick", functionName);
    ...return false prevents the default but not propagation, just like a DOM0 handler. Try it here (using IE8 or lower).
  • jQuery handlers: Event handlers hooked up with jQuery get a twofer: return false both prevents the default and stops propagation. It's a jQuery thing.

Happy handling!

Sunday, 30 January 2011

Skipping the protocol

I just found out about this incredibly useful trick for loading absolute resources with either http: or https: depending on the protocol with which your page was loaded (to avoid those "mixed content" complaints from browsers).

Amazingly, you can just leave the scheme (protocol) part off the URL entirely. So for instance, if you're loading jQuery from the Google CDN with this path:

<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js'></script>
you can load it like this instead:
<script src='//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js'></script>
If the page that's in is served via http, that path will become
http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js
If it's https, that will become
https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js
E.g., it's a path relative to the protocol (scheme) but in all other ways absolute.

(Naturally, if you load a file via the file: protocol — e.g., locally — it will try to resolve that locally and blow up. But you don't do that, do you?)

Don't trust it? Neither did I, but I haven't found a browser in which it doesn't work, nor apparently have these guys.

And you thought you knew all there was to know about URIs...

Wednesday, 8 December 2010

Ever wondered what browsers support <insert feature here>?

There's a site for that: caniuse.com.

So, for instance, what browsers support the File API? These ones: http://caniuse.com/#search=file api.

Friday, 3 September 2010

Brilliant - A periodic table of elements

Josh Duck has done a Periodic Table of the Elements for HTML5. Brilliant (and pretty). In the 20 or so years of HTML, surely someone has thought of this concept before — but if so, I'm certainly not aware of it. Props to Josh!

Tuesday, 16 March 2010

...by any other name, would smell as sweet

Although it's not a new problem, lately I've been seeing so many people running into a specific issue with Internet Explorer that I thought it worth just jotting down what the problem is and how to get around it.

The problem, in brief, is conflation. Internet Explorer (v6 and v7) mixes together the namespaces of the id and name attributes, which should be completely distinct from one another. id, you'll recall, must be unique within the document; it uniquely identifies an element. name, on the other hand, is not for uniquely identifying things (well, not mostly). It's used for a couple of different things, such as giving form fields the names they'll have when submitted, or giving anchors a name. There's no requirement that name values be unique — in fact, when doing forms, there are lots of reasons for using the same name for multiple fields (radio buttons, for example).

Unfortunately, the Internet Explorer engine will find elements by name sometimes when it really shouldn't, specifically when you're using document.getElementById. So for instance, say you have a form in your document with a 'stuff' field:

<input type='text' name='stuff'>
and later in that same document you have a div with the id "stuff":
<div id='stuff'>...</div>
Consider this code:
var elm;
elm = document.getElementById('stuff');
if (elm) {
alert("The element's tagName is " + elm.tagName);
}
else {
alert("Couldn't find the element.");
}
In a browser that implements document.getElementById correctly, that should alert "The element's tagName is DIV". But on IE, it will alert "The element's tagName is INPUT" because it incorrectly finds the input field. The only way around this is to change the id or name of one element or the other.

Another related problem is that id values are not case-sensitive in IE6 or IE7, although of course the standard says they should be. So it'll also confuse an element with the id (or name) 'stuff' with one with the id (or name) 'Stuff'. (To be fair, surely you and I would as well?)

There's good news, though: Microsoft does document the behavior, and they've fixed it in IE8, so there's hope for the future.

Perhaps slightly OT, but lest people accuse me of Microsoft-bashing (er, I have been known...), let me just remind everyone who brought us XMLHttpRequest (the basis of Ajax) and innerHTML, both of which I use (directly or indirectly) in nearly every JavaScript-enabled browser project I do — and I bet you do too. So hey, they got many things wrong, but got some things very right as well. Also useful to remember — as we continue to bash IE6 with repeated shouts of "Die! Die!" — just how much amazingly better (faster, less crash-prone, more feature-rich) it was than its chief rival, back in the day.

Saturday, 29 March 2008

What's in a name?

Micro-post today, folks:

You see a fair bit of confusion from newbies in mailing lists around the "name" attribute vs. the "id" attribute. (Edit 21 March 2010: Confusion not helped by a bug in Internet Explorer; more here.) For instance, I recently saw a "how do I do this" -style post asking how to deal with a form, with the sample being:

<form name='form1'>
<label><input type='checkbox' id='cb1'> Checkbox 1</label>
</form>
The poster wanted to know how to retrieve the form and submit it (along with some further information) via Prototype's Ajax.Updater. So he wanted to use the serialize() method Prototype adds to form elements when it extends them (e.g., when you retrieve the element using $()).

Consequently, the use of "id" and "name" attributes in his example was exactly backward: He wanted to be able to retrieve the form using $(), which is a general-purpose routine that retrieves elements by their unique ID, and then have the form fields submitted -- but the form field had no name.

Here's the mantra:
Elements have IDs; form fields have names.
IDs are unique in the document; form field names are not (necessarily).

Two further notes:

1. Form fields can also have IDs if you need to refer to their elements in your code (to enable/disable them, etc.), but in terms of sending in a form, fields have names.

2. You don't have to use an ID to get at the element for a form; you can use a name and then get at the form element via document.YourFormName in your JavaScript code. But nowadays we mostly look elements up by their unique IDs; and in the specific case of the question from the poster above, since he was going to want to use $(), he would want an ID.