giancarlo.dimassa.net A web programmer's blog

2Jul/070

Optimize pages for search engines with dynamic CSS/javascript HTML building (how to make your own lightbox working example!)

CSS, DHTML and Javascript work really good together. In fact, I tend to use the combination to replace Flash whenever it's appropriate (usually, most of the time!).
Javascript 'building' is a technique where you dynamically add original nodes to your DOM, usually based on existing content.
Speaking in (sort of) plain english, this means you can create a slideshow from an unordered list, a tabbed or sliding control set from a group of divs, an image viewer from a link (everyone now knows Lightbox v2 by Lokesh Dhakar).

For the sake of simplifying this article, the examples will be done using the Prototype and the Scriptaculous Javascript libraries. However these are not needed to produce these results, and you can do everything without them, or with other libraries (JQuery or Moo.Fx to name some).

Adding an element with these libraries loaded is a matter of writing this simple line of code:

newelement = Builder.node('div',{className:'myclass','html content');

then you append it to a parent element, this way

parentelement.appendChild(newelement);

it's simple as that!
The parent element can be any valid HTML element in the DOM, for example the document body

parentelement = document.getElementsByTagName('body')[0];

After adding the element dynamically, you can style it using CSS

.myclass {
position:absolute;
top:49%;
left:49%;
width:200px;
height:200px;
border:2px solid black;
background-color:white;
color:black;
padding:10px;
}

And you got a nice new square floating near the center of the viewport, built entirely by two lines of javascript! Search Engines doesn't see it (yet!) as it is dynamically generated.

Now, one step further:

Let's imagine we got this HTML somewhere in our document:

<a href="/img/photo.jpg" id="mylink"><img src="/img/photo_thumbnail.jpg" /></a>

you can seek it into javascript and modify it's functions based on its data, so that it does something different from initially, using this new "dynamic building" technique.
add this to your html document, after the prototype and scriptaculous lines

<script type="text/javascript" language="javascript1.2" src="/javascript/dynamic.js"></script>

then in this dynamic.js script write this

function onloadfunc() {
}

Event.observe(window, "load", onloadfunc);

this way the onloadfunc function will be executed after the document load. Why not before? Because if you execute the javascript before all the page is loaded, there's the risk that our anchor link has not been added yet to the DOM, because the file has not been fully downloaded and processed.
Event.observe is another prototype/scriptaculous function, it attaches events to javascript object, we used it to attach the onloadfunc function to the window object, at the end of the load event.
A wrong practice is to do simply this

window.onload = onloadfunc();

don't use this sintax because if there are other functions that need to be executed on window load, and have been attached before (maybe from other scripts) you will delete them. Your code will start to "not play nice".

Done everything? It's time for the magic to happen!

Now we got a function that gets executed on each page load, and we know how to dynamically generate HTML element from javascript. We only need to know WHEN to generate these elements!

The best way is to "leverage" existing content and markup. Let's take our anchor, remember? It's original function is to go to a page with the photo in it. Why not load the photo in a nice box on the center of the screen (where did you already see that happening...) ?
But how to do so?
We can override the anchor default click function with a new onclick event definition. Have you ever done that?

<a href="#" onclick="alert('this is a sample')">Click me!</a>

that produces

Click me!

The problem with this is that you strictly need javascript to execute this function. Instead, with the link we wrote before, everyone can see the photo, even if the browser has not Javascript activated... even search engines!
We attach these new onclick functions in the onloadfunc function, doing so

$('mylink').onclick = function(
// this will happen when the link is clicked
return false;
)

hmm.. do you feel nasty for having the anchor do everything you want, now? Let's take a further look at these lines
$('mylink') is a prototype/scriptaculous shortcut for document.getElementById, it will pick the element with that id. We set the id when writing the anchor, remember?
Now, you can do everything with this element, because you 'picked' it.
To assign a new function to his onclick event, you use this syntax
$('mylink').onclick = newfunc();

where newfunc(); can be defined somewhere else.
I instead used a contracted syntax, I didn't want to define another function, so I used a javascript technique called "inline definition": I write the function when I want it, and I don't even bother giving it a name.
In this function I can do whatever I want, but I should remember to tell it to return false at the end, otherwise the original anchor click function will be executed after the function. This means the new page with the picture would be loaded after the function. If you tell it to return false, the function will tell the element to stop behaving normally (like a normal anchor).
It's the same technique used to verify form contents before submitting!

If we write our html building code into this function, it will be executed instead of the default anchor behaviour!
So the function becames

$('mylink').onclick = function(
parentelement = document.getElementsByTagName('body')[0];
newelement = Builder.node('div',{className:'myclass','html content');
newimg = new img();
newimg.src=$('mylink').href;
parentelement.appendChild(newelement);
newelement.appendChild(newimg);
return false;
)

we're done! The image will be displayed in a popup similar to the famous Lightbox!

Let's sum up everything:

  • We need to always produce content that is readable by search engines and users that do not have javascript enabled. You can do that by 'leveraging existing content'.
  • You should create a function that gets executed on page load and adds new functions to loaded HTML markup.
  • There are a lot of libraries that will help you in dynamic building, use them! They will take care of the different browser quirks. The examples use the Prototype and Scriptaculous
  • You will need to style the new content using CSS.

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment


No trackbacks yet.

Community

Already a member?
Login
Login using Facebook:
Last visitors
view more...
Powered by Facebook

Tags