JQuery_ Novice to Ninja - Earle Castledine [73]
(2)
We store a reference to that parent element inside a variable. What’s unusual here is that we’re using a property of our TT object instead of a global variable. We’ll come back to this in the next chapter, but for now just know that it’s much the same as writing var current = $(this);.
(3)
We’re using the familiar setTimeout function, except that this time we’re saving the timer to a variable. This is so we can turn it off by name if we need to. We’re accessing the delay property we set before as the second parameter for setTimeout. As we’ve seen, this is how long the browser will wait before displaying the tooltip.
(4)
When the user mouses off the target, we want to stop the timer so that the tooltip will stay hidden after the delay expires. We do this with the JavaScript clearTimeout method, passing in the reference to our timer.
Okay, so now that our hover handler is set up, we need to determine the position of each of our tooltips. We’ll use each() to loop over them, but first we’ll grab the height and width of the screen. If we were to do this inside the loop, jQuery would need to calculate those values once for each tooltip, even though they’re always the same. By storing the values outside the loop, we avoid this wasteful calculation and improve the performance of our script:
chapter_05/18_advanced_tooltips/script.js (excerpt)
var screenWidth = $(window).width();
var screenBottom = $(window).scrollTop() + $(window).height();
$(".tooltip").each(function() {
// grab the containing element
$container = $(this).parent();
// give it relative position if required
if ($container.css("position") != 'absolute'
&& $container.css("position") != "fixed") {(1)
$container.css({position: 'relative'});
}
var totalHeight = $container.height() + $(this).outerHeight();(2)
var width = $(this).outerWidth();
var offset = $container.offset();
// now we get the position the tip
var top = $container.height(); // default placement(3)
var left = 0;
This part of the code should be a little easier to understand. We loop over each tooltip on the page, and first store a reference to the container element just to avoid having to write $(this).parent() over and over. Notice that the variable name starts with $: this is just to help us remember that the variable contains a jQuery selection. Here’s a breakdown of the contents of the loop:
(1)
We check to see if the parent element has position: absolute; or position: fixed;. It has to be positioned, since we’ll be using position: absolute; to offset the tooltip from it. If it already has absolute or fixed, we’ll leave it that way. If it doesn’t, though, we’ll give it position: relative;.
(2)
We need to know the total combined height of both the tooltip and the parent element, so we store that in a variable to use later.
(3)
By default, we give the tooltip a top position equal to the height of the container. This means it will appear directly below the container (since it is offset from the top by exactly the container’s height).
Note: Logical Operators
In JavaScript, when you’re testing for values in an if statement, you can use the && operator to mean and. So in the above example, the contents of the if block will only execute if both conditions (on either side of &&) are met.
You can also write || (two pipe symbols) to mean or. If we’d used that instead of && above, the contents of the if block would execute if either condition was met.
This is good work so far! We’re almost done, but we need to fix one small problem: what if the tooltip’s position takes it off the screen? If the target element is right at the bottom of the screen, and we want the tooltip to appear below it, the tooltip will remain unseen!
It’s time for a little collision detection. We need to find out if the tooltip is hitting either the bottom or right edge of the screen. Let’s have a look at how we accomplish this:
chapter_05/18_advanced_tooltips/script.js