DOM Traversing

oldest first | newest first

Fancy Drop Cap – Part 1

Introduction

Last spring when I implemented a new design for my weblog, I wanted to use a fancy drop cap for the first letter of the first paragraph of the first post of each page. There are all sorts of ways to make a drop cap happen, but since I was reading Jeremy Keith's excellent book DOM Scripting at the time, I thought I'd do it that way. The DOM scripting method that I put together had some important benefits for me at the time:

  • It used an image, so I didn't have to worry about installed fonts on users' machines
  • The HTML source stayed intact, so search engines wouldn't trip over a first word with a missing first letter.
  • It degraded nicely, so if users had JavaScript or images or both turned off, everything would still look fine, just a little less pretty.

Now that I'm learning jQuery, I thought I'd revisit my code and see if I could tidy it up a bit, the jQuery way.

Image Set

AI first put together a set of images, one for each letter of the alphabet, using a font from the Dieter Steffman collection at typOasis. If you don't want to go through the laborious process of converting letters into images, you can download mine (20KB zip). See the letter "A" floating to the right of this paragraph for an example.

Setting up the Code

Instead of putting all of the code in a $(document).ready() function, I created a separate function and just called it inside $(document).ready():

JavaScript:
  1. $(document).ready(function() {
  2.   swap_letter();
  3. });
  4. function swap_letter() {
  5.   //all the code goes here
  6. }

Now we can get down to business.

Insert Image Here

The easiest part of the process was inserting the image, because jQuery makes it almost effortless. Read the rest of this entry »

Fancy Drop Cap – Part 2

In Fancy Drop Cap - Part 1, I showed how I used jQuery to insert a drop cap on my personal weblog. But there is still some unfinished business to take care of:

  1. Accounting for cases in which the first paragraph (where I want my drop cap to go) starts with another tag of some sort (<a href="...">, <em>, etc.)
  2. Adding a little CSS to the drop cap

So let's begin with item 1. As you may recall, we defined three variables, first_paragraph, first_letter, and text. The variables allowed us to get the value of the textNode of the first letter of the first paragraph, so we could replace it with the image. Here is what that part looked like:

JavaScript:
  1. var first_paragraph = $('#main-content p')[0];
  2. if (!first_paragraph) return false;
  3. var text = first_paragraph.firstChild.nodeValue;
  4. var first_letter = text.substr(0,1);
  5. if ( text ) {
  6.   first_paragraph.firstChild.nodeValue = text.slice(1);
  7. }

The only problem with that code is that line 3 assumes that the first child node of the first paragraph is actually a text node. But what if it's a span tag (<span>) or a link (<a href="...">)? Well, in that case we'll need to keep drilling down through the nodes until we can't go any farther.

Loop the Loop

To do that, we'll set an intermediate variable, called node, initially making it the same as first_paragraph:

JavaScript:
  1. var node = first_paragraph;

Next, we change our node variable to be defined as the first child of that node (node = node.firstChild), and we keep doing that until there are no more child nodes left, by using a "while" loop:

JavaScript:
  1. while (node.childNodes.length) {
  2.   node = node.firstChild;
  3. }

So, in other words, as long as there is a child node, our variable will be reset as that child node.

The First Letter — and Only a Letter

When that's all done, we set our text variable, this time as the value of our node variable:

JavaScript:
  1. var text = node.nodeValue;

Now all we have to do is get the first letter of the text so that we can replace it with the drop-cap image: var first_letter = text.substr(0,1).

There is just one more thing that we should account for Read the rest of this entry »

Quick Tip – Blurring Links

With all the fun new things you can do using jQuery and other JavaScript libraries, people are using links ("a" tags) for much more than sending users to a different page. One little annoyance I've found when using links for these events, though, is the little dotted outline that appears around the linked words upon clicking them and making them "active."

dotted link outline

It makes sense to see the outline when clicking, but I don't want it to stay there.

In Firefox 1.5 and up, it's easy to get rid of the outline with a little CSS:

CSS:
  1. a:focus, a:active {
  2.   outline: none;
  3. }

Unfortunately, that doesn't work in Internet Explorer 6 and below (is anyone surprised?).

Wouldn't it be nice to get rid of the outline in every browser (as long as JavaScript is enabled, of course)?

jQuery to the Rescue

  • The trick is to take the focus off the link once it has been clicked, and jQuery makes that simple. In the jQuery Discussion List, Klaus Hartl offered this snippet, which works perfectly:
  • JavaScript:
    1. $('a').click(function() {
    2.   this.blur();
    3. });

    Or, if you wanted to apply the blur only to links inside a DIV with an ID of "magic," for example, you could replace $('a') with $('#magic a'). If the blur should apply only to links with a class of "fun," the selector would change to $('a.fun'). See how easy? Give it a try:

    click me and I won't show the ugly dotted outline

    For this little demo, I gave the link a class of "fun" and put the above jQuery code inside $(document).ready() (For more on $(document).ready(), see Introducing $(document).ready() ). I also added return false; because I didn't want the link to take you anywhere.

    How to Get Anything You Want – part 1

    With jQuery, you can get to just about anything on a web page. In this entry, I'll show you a few ways you can use jQuery's versatile selector expressions to traverse to an element — or group of elements — in the DOM.

    I've put together a short paragraph and an ordered list scattered with inline elements such as <em>, <code>, and links. It's all wrapped in a DIV with an ID of "jqdt," which allows me to focus the demonstration to one area of this page.

    Read the rest of this entry »

    How to Get Anything You Want – part 2

    A couple weeks ago I wrote about traversing the DOM with jQuery's selector expressions to get any elements in the document (see How to Get Anything You Want - part 1). This time around, I'm going to focus on jQuery methods that provide even more ways to get elements. Some of these methods have a nearly identical counterpart among the selector expressions, but for the most part, the two ways of getting elements complement each other.

    Read the rest of this entry »

    Multiple Fancy Drop Caps

    After I wrote a couple entries (Fancy Drop Cap, Part 1 and Part 2) on creating a drop cap for the first paragraph in a DIV, a couple people asked how one would go about making the drop cap apply to every paragraph in a DIV.

    Update

    I've written a Fancy Letter Plugin that does all the hard work for you. You write a line of jQuery like $('div.content p').fancyletter(). The plugin wraps the first letter of the selected elements in a <span> with class names that you can then style to your needs.

    Most of the code can remain the way we left it in Fancy Drop Cap - Part 2. We created a swap_letter() function to:

    1. find the first letter of the paragraph
    2. concatenate that letter with the rest of an image tag if it matches one of the letters in a regular expression
    3. strip the letter out of the paragraph since we want to replace it with the image
    4. prepend the image tag to the paragraph

    We also gave the image a class name of "fancy-letter" so that we could style it a bit:

    Read the rest of this entry »