DOM Modification Entries

Effect Delay Trick

Wednesday, January 17th, 2007

Here is a quick trick for getting an effect to delay without using setTimeout.

Let’s say, for example, that I want to show an alert message on the page every time a user clicks on a certain button. But I don’t want it to stay there forever; I want it to go away a few seconds later. You know, like the way they do in all of those crazy Web 2.0 sites.
(more…)

Multiple Fancy Drop Caps

Tuesday, December 12th, 2006

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.

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:

CSS:
  1. .fancy-letter {
  2.  float: left;
  3.  margin: -1px 2px 2px 0;
  4. }

So, what needs to change? Not much actually.

The first thing to do is remove the line that sets the "first_paragraph" variable: var first_paragraph = $('#main-content p')[0]. In its place we'll use jQuery's .each(), which takes the pain out of for loops. All of the work will be done inside this .each() method, starting with setting a variable for "each" of the paragraphs:

JavaScript:
  1. $('#drop-caps p').each(function(index) {
  2.   var paragraph = this;
  3.   . . .
  4. });

We set the paragraph variable as this instead of $(this) for the same reason that we had (in the earlier entries) put the [0] after $('#main-content p') instead of writing $('#main-content p:eq(0)'): because we need to work on the actual DOM node. Also, note that I changed the DIV's id from "main-content" to "drop-caps" for this example, but you can name yours whatever you want.

The rest of the code is pretty much the same, because all we really needed to do was get a different set of elements Here is the new code in all its glory:

JavaScript:
  1. $(document).ready(function(){
  2.   swap_letter();   
  3. });
  4.    
  5. function swap_letter() {
  6.   $('#drop-caps p').each(function(index) {
  7.     var paragraph = this;
  8.     var node = paragraph;
  9.     while (node.childNodes.length) {
  10.       node = node.firstChild;
  11.     }
  12.     var text = node.nodeValue;
  13.     var first_letter = text.substr(0,1);
  14.  
  15.     var match = /[a-zA-Z]/.test(first_letter);
  16.     if ( match ) {
  17.       node.nodeValue = text.slice(1);
  18.       $('<img />')
  19.           .attr('src','/images/alphabet/' + first_letter.toLowerCase() + '.gif')
  20.           .attr('alt',first_letter)
  21.           .addClass('fancy-letter')
  22.           .prependTo( paragraph );
  23.       first_letter = "";
  24.     }
  25.   });
  26. }

For an explanation of the other parts, please refer to Fancy Drop Cap - Part 2 and Fancy Drop Cap - Part 1. In the meantime, feast your eyes on the beauty of these fancy first letters.

This is the first paragraph. The "T" in "This" should be replaced by the drop-cap image. The image is floated left with a little padding to the right and the bottom.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Really Simple Live Comment Preview

Sunday, November 19th, 2006

Introduction and Caveat

I'm sure that some of you were expecting this entry to discuss traversing the DOM using jQuery methods. After all, I said I would do just that in my last entry. But a couple nights ago, I had the impulse to try a "live comment preview," so I'm going with it. My next entry, then, will be "How to Get Anything You Want - Part 2." I promise.

Please keep in mind as you read through this tutorial the "learning" part of this site's title: I'm learning jQuery just as many of those who will read this entry are. I mention this now because I have the nagging feeling that it was just too easy to create the live preview. Surely I must be doing something wrong. As always, I am counting on the superior knowledge of my readers to point out where my code fails. But enough of the apologies. Let's get started.

Quick Setup

For the live preview I started with the default comment form in WordPress's Kubrick template:

HTML:
  1. <form action="..." method="post" id="commentform">
  2.   <p><textarea name="comment" id="comment" cols="100" rows="10" tabindex="4"></textarea></p>
  3.   <p><input name="submit" id="submit" tabindex="5" value="Submit Comment" type="submit">
  4.   <input name="comment_post_ID" value="30" type="hidden">
  5.   </p>
  6. </form>

The important part here is the textarea's id="comment". We want to show the contents of that textarea as the user inputs them.

Create the Preview DIV

Now on to the jQuery code. (more...)

Fancy Drop Cap - Part 2

Monday, October 2nd, 2006

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 (more...)

Fancy Drop Cap - Part 1

Wednesday, September 20th, 2006

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.  
  5. function swap_letter() {
  6.   //all the code goes here
  7. }

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.

(more...)