Tag Archives: HTML element

jQuery tooltip plugin!

Tooltips and jQuery

In order to complete the tooltip post series I decided to make a plugin for jQuery that implements tooltips in the most simple way I was able to find! I have no idea what are the other plugins for tooltips and I never used such plugin, but however I needed one in order to complete my task an suddenly I turn it into a plugin.

What I’d like to hear is requests for improvements and bugs reported, just to make the plugin as useful as possible.

Let’s start in that post with some primary HTML markup, here are the complete source and demo page.

<html>
<head>
 <title>jQuery tooltip</title>
</head>
<body>
<p>A DIV element wrapped in another DIV that's 800 pixels wide and thus defines the bounds</p>
<div id="wrap" style="width:800px;border:1px solid blue;">
 <div id="container" title='test' rel="here's some<br />HTML and image<br /><img src='/jquery-logo.png' />" style="border:1px solid red;">
 <p>
 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer rhoncus vulputate arcu in mollis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla nunc libero, eleifend in imperdiet lacinia, pellentesque eget turpis. Nulla consectetur augue vulputate arcu porta tempus. Mauris nisl risus, fermentum posuere sodales sed, accumsan in massa. Pellentesque facilisis, felis sit amet vulputate egestas, nibh lacus sollicitudin nulla, non commodo nunc elit et eros. Nulla eu placerat mauris. Phasellus sit amet odio nec dui pharetra pulvinar. Nunc sollicitudin, nisl quis interdum consequat, diam dolor condimentum felis, ac porttitor turpis augue nec sapien. Quisque pulvinar nulla ut elit dapibus in tempus ipsum interdum. Pellentesque feugiat tempus tortor, mollis fringilla ligula faucibus nec. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus ullamcorper lacus. Maecenas at blandit justo. Maecenas adipiscing velit luctus mauris gravida adipiscing. Morbi molestie ipsum metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec sapien mi, hendrerit sit amet semper ut, condimentum et risus. Nulla facilisi.
 </p>
 </div>
</div>
<p>When defined over an image the tooltip gets the text into the alt attribute by default</p>
<img id="my-img" src="/jquery-logo.png" alt="test" />
<p>When you attach the .tooltip() method on a link it gets its title attribute for the tooltip by default. Note that you can add more and more links after you attach the .tooltip() method on that class name. This is because the plugin make use of the .live() method of jQuery</p>
<a href="http://stoimen.com" title="a title of the link">Just a link!</a>

And right after that the JavaScript:

<!-- include the jQuery library -->
<script src="/jquery-1.3.2.js"></script>
<script>
// this is the plugin code. You can copy/paste it at the bottom of the jquery.js library file
(function(jQuery) {
 jQuery.fn.tooltip = function(options) {
 $('body').append('<div id="sstt" style="display:none;"></div>');
 if (typeof options == 'undefined') options = {};
 this.live('mousemove', function(e) {

 var att = 'attribute' in options && $(this).attr(options.attribute);
 if(!att) att = $(this).attr('rel');

 var bbox = 'bbox' in options && options.bbox;
 if (!bbox) bbox = $(document);

 if ('text' in options && options.text) att = options.text;

 if ($(this).is('img')) att = $(this).attr('alt');
 if ($(this).is('a')) att = $(this).attr('title');

 var elem = $('#sstt'),csstxt = elem.css('cssText'),ew=elem.width(),dw=bbox.width(),px=e.pageX+10,py=e.pageY+10;
 elem.html(att);
 var eloffset = dw > px+ew &&
 elem.css('cssText', csstxt+';position:absolute;top:'+py+'px;left:'+px+'px;display:block');

 !eloffset &&
 elem.css('cssText', csstxt+';position:absolute;top:'+py+'px;left:'+(dw-ew)+'px;display:block');
 });
 this.live('mouseout', function() {
 $('#sstt').hide();
 });
 };
})(jQuery);

How to setup the options?

The .tooltip() method has an optional “options” parameter that specifies simple parameters for the tooltip itself.

{
 attribute : 'rel',
 bbox : $(document),
 text : ''
}

By default the plugin uses the REL attribute for the text of the tooltip, but you can override it by setting the options attribute property:

var options = { attribute:'title'}

Here the tooltip will take the TITLE attribute value. Note that the TITLE attribute is default for anchor tags and the construction above will be default for them. Over links the .tooltip() method gets the ALT attribute.

bbox is the default bound box for the tooltip. Default value is $(document), but it can be any other jQuery object. Look at the examples bellow.

text is predefining the tooltip’s text.

Finally some examples

1. Usage with no options. The REL attribute is considered as text for the tooltip and the bound box is the document:

$('#container').tooltip();

2. Usage with bound box. The REL is yet again considered as text for the tootip and the bound box is passed as argument as a jQuery object.
2.1. The parent element:

$('#container').tooltip({bbox:$('#container').parent()});

2.2. Explicit defined parent element:

$('#container').tooltip({bbox:$('#wrap')});

3. Predefine the text of the tooltip:

$('#container').tooltip({text:'Hello World!'});

3.1. It can be even HTML formatted text:

$('#container').tooltip({text:'Hello <br /> World!'});

4. Predefine the attribute. Now the default REL is dismissed and the TITLE is considered for the tooltip:

$('#container').tooltip({attribute:'title'});

5. Default for image is not REL but the ALT attribute:

$('#my-img').tooltip();

6. Default for link is not REL, but the TITLE attribute:

$('.my-link').tooltip();

7. You can even add some links from the same class on the fly, but they are still working, because of the live event binding:

$('body').append('<a href="http://stoimen.com" title="another link">some other link</a>');

Prevent link default action when mousedown and mouseup fires!

What is preventing default?

I’m sure you know how to prevent the default action of a link when onclick event is attached to it. Yes, it is a common task and by simply adding a return false; at the end of the method called on click it simply doesn’t call the refresh the page. This is really an everyday task. To describe it first, let’s imagine there’s a link with # href value:

<a onclick="”myFunc()”" href="”#”">click here</a>

Than the definition of myFunc() is something like that:

function myFunc() {
   ...
   return false;
}

If that “return false” part was missing you simply get additional # in the uri of the page and worse – you may be scrolled to the top of the page, because of the lack of an anchor with empty name.

OK, but we know how to deal it! But what happens when you don’t attach click event but mousedown/mouseup pair? It may seem the same thing but it is not!

When you place return false on both event handlers of the mousedown/up events nothing happens, there is a # on the end of the uri and yes the document is scrolled.

How the prevent the default action?

Simply by adding onclick event! We already know that this is working and prevents the default action. Just do the following:

$(‘#element_id’).mousedown(function(){
    ...
    return false;
});
$(#element_id’).mouseup(function() {
   ...
   return false;
});

// this doesn’t work like preventing the default refresh
// action until ....
$(‘#element_id’).click(function() {
   return false;
});
// is added

OBJECT & … forget about EMBED tag!

Actually most of us think about OBJECT and EMBED tags as inseparate pair. The reality is different. In fact you don’t need to use the EMBED tag.

Only by using the OBJECT tag you ensure it will be interpreted correctly by every browser.

As you may know, the EMBED tag is supported by Gecko and WebKit, but not by IE. On the other side the OBJECT tag is supported by every one.

Why than the most common usage is with OBJECT and EMBED? That’s by me because of misunderstanding of the semantics of those two!

jQuery live() vs bind() performance

1. What is event delegation in JavaScript?

To start with some example let’s assume that there is one DIV element with 100 A tags inside. If you assign event to every A tag that as you may know slowes down your browser. That’s a problem because sometimes that can happen, even with more than one hundred A tags. Imagine you’ve a map with one thousand markers, which are A tags. Attaching events slowes down the browser, because every of these A tags bubbles the event that has been fired. And that makes your CPU to make thousands of calculations. Of course you can avoid this problem with a simple technique. Just attach one single event on the container DIV element. Thus you can check if some child of the DIV element has been the target of the event. This makes the browser to breath. Continue reading jQuery live() vs bind() performance