JQuery_ Novice to Ninja - Earle Castledine [74]
// re-position if it's off the right of the screen
if (offset.left + width > screenWidth) {
left = 0 - width + 42;
$(this).addClass('left');
} else {
$(this).removeClass('left');
}
// re-position if it's off the bottom of the screen
if (offset.top + totalHeight > screenBottom) {
top = 0 - $(this).outerHeight();
$(this).addClass('above');
} else {
$(this).removeClass('above');
}
We check to see if the tip’s horizontal or vertical offset, plus its width or height, is greater than the width or height of the screen (which we calculated earlier). If it is, we modify the top or left property respectively, and assign a class that we’ll use to display the appropriate part of our background image sprite.
The final (and easiest) step is to use the css action to assign the calculated top and left properties to the tips:
chapter_05/18_advanced_tooltips/script.js (excerpt)
$(this).css({
"top": top,
"left": left
});
We’ll call our setTips method on document-ready, and also each time the window is resized, to ensure that our tips are always adequately positioned:
chapter_05/18_advanced_tooltips/script.js (excerpt)
$(document).ready(function() {
TT.setTips();
});
$(window).resize(function() {
TT.setTips();
});
With that code in place, we just need to add some CSS to position our background sprite appropriately, based on the classes we assigned:
chapter_05/18_advanced_tooltips/tooltip.css (excerpt)
span.tooltip.left {
background-position: 100% 0;
}
span.tooltip.left span {
padding: 15px 0 0 17px;
}
span.tooltip.above {
background-position: 0 100%;
}
span.tooltip.above span {
padding: 13px 0 0 12px;
}
span.tooltip.above.left {
background-position: 100% 100%;
}
span.tooltip.above.left span {
padding: 13px 0 0 17px;
}
Warning: IE6 Support
Although jQuery does a fantastic job of handling cross-browser issues in our JavaScript code, it’s not so good for our CSS. The above style rules rely on chaining several class selectors together. This will confuse Internet Explorer 6, which will only see the last class in any style rule. Moreover, our PNG image relies on alpha-channel transparency for the tooltip’s drop shadow, and this is also unsupported by IE6.
Over the last few years, several major sites (including YouTube and Facebook) began phasing out support for IE6. This doesn’t mean that they totally ignore this browser, rather that they accept that IE6 users will receive a degraded experience (perhaps similar to what visitors without JavaScript will see).
For our tooltip example, we could use conditional comments to target some styles specifically to IE6 and provide it with the same tooltip functionality—except using a flat background image without a thought-bubble style or a drop shadow. This way, the background position would be inconsequential, and the PNG issue solved.
And there you have it! The final tooltip not only waits to see if you really meant for it to display, but it also shifts its position to make sure it’s fully visible whenever it does display! Because we’ve avoided linking this code to anything specific on our page, it’s easy to reuse this script on any other page—you just need to include a few spans with a tooltip class, and you’re off to the races. This is an important lesson: you should always try to structure your code in such a way that you can reuse it later. This will save you work in the long run, and give you more time to experiment with cool new functionality instead of rebuilding the same old widgets every time you need them.
Order off the Menu
Whew! That was a hard sprint to the finish line. Over the course of this chapter, we’ve ramped up our jQuery know-how and used it to move beyond simple hiding and revealing, and well into the territory of the true UI ninja. You’ve learned how to reduce complexity on the screen by packaging up links and widgets into collapsing menus, accordions, panels, and tooltips.
In the next chapter, we’ll look at reducing complexity in our code, and then tackle what’s ostensibly the most important