Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ TipTip

Copyright 2010 Drew Wilson

Modified by: indyone (https://github.com/indyone/TipTip)
Modified by: Jonathan Lim-Breitbart (https://github.com/breity/TipTip) - Updated: Oct. 10, 2012
Modified by: Alan Hussey/EnergySavvy (https://github.com/EnergySavvy/TipTip) - Updated: Mar. 18, 2013

http://www.drewwilson.com
http://code.drewwilson.com/entry/tiptip-jquery-plugin

Expand Down Expand Up @@ -60,4 +64,27 @@ What's New:

* The option "activation" can have the value "manual". In this case no events will be applied to the element and the developer will be responsible to show or not the tooltip. But you can always use the show and hide methods to show or hide the tooltip ;-)

* Created an alternate look & feel for TipTip, you can use it by setting the option "cssClass" to "alternative".
* Created an alternate look & feel for TipTip, you can use it by setting the option "cssClass" to "alternative".

-------------------------------------------------------------------

More updates (Jul. 27, 2012):

* Fixed tooltip flickering that occurred when hovering over the edge of a tooltip's trigger element.
This was being caused by the tiptip_arrow overlapping the trigger element. CSS and arrow positioning
have been modified to resolve this. CSS was inspired by Toorshia's CSS in TipTip discussion thread
(see https://drew.tenderapp.com/discussions/tiptip/32-tool-tip-flickers-when-hovering-the-border-of-a-tiptip-link).

* When keepAlive option is set to true, tooltip now hides both when the mouse leaves the tiptip_holder (like before)
as well as when mouse is clicked anywhere other than the tooltip itself. (Appropriated from James Simpson's miniTip plugin:
http://goldfirestudios.com/blog/81/miniTip-jQuery-Plugin).

-------------------------------------------------------------------

More updates (Mar. 18, 2013):

* Added two new options, hideOnClick and delayHide:

* hideOnClick takes a feature previously added to keepAlive, and makes it optional.

* delayHide adds an optional delay before the tooltip will be hidden. This option pairs well with hideOnClick.
181 changes: 129 additions & 52 deletions jquery.tipTip.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,44 @@
/*
* TipTip
* Copyright 2010 Drew Wilson
* www.drewwilson.com
* code.drewwilson.com/entry/tiptip-jquery-plugin
*
* Version 1.3 - Updated: Mar. 23, 2010
*
* This Plug-In will create a custom tooltip to replace the default
* browser tooltip. It is extremely lightweight and very smart in
* that it detects the edges of the browser window and will make sure
* the tooltip stays within the current window size. As a result the
* tooltip will adjust itself to be displayed above, below, to the left
* or to the right depending on what is necessary to stay within the
* browser window. It is completely customizable as well via CSS.
*
* This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
* TipTip
* Copyright 2010 Drew Wilson
* www.drewwilson.com
* code.drewwilson.com/entry/tiptip-jquery-plugin
*
* Modified by: indyone (https://github.com/indyone/TipTip)
* Modified by: Jonathan Lim-Breitbart (https://github.com/breity/TipTip) - Updated: Oct. 10, 2012
* Modified by: Alan Hussey/EnergySavvy (https://github.com/EnergySavvy/TipTip) - Updated: Mar. 18, 2013
*
* Version 1.3 - Updated: Mar. 23, 2010
*
* This Plug-In will create a custom tooltip to replace the default
* browser tooltip. It is extremely lightweight and very smart in
* that it detects the edges of the browser window and will make sure
* the tooltip stays within the current window size. As a result the
* tooltip will adjust itself to be displayed above, below, to the left
* or to the right depending on what is necessary to stay within the
* browser window. It is completely customizable as well via CSS.
*
* This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/

(function ($) {
$.fn.tipTip = function (options) {
var defaults = {
activation: 'hover', // How to show (and hide) the tooltip. Can be: hover, focus, click and manual.
keepAlive: false, // When true the tooltip won't disapper when the mouse moves away from the element. Instead it will be hidden when it leaves the tooltip.
keepAlive: false, // When true the tooltip won't disappear when the mouse moves away from the element. Instead it will be hidden when it leaves the tooltip.
maxWidth: '200px', // The max-width to set on the tooltip. You may also use the option cssClass to set this.
edgeOffset: 0, // The offset between the tooltip arrow edge and the element that has the tooltip.
defaultPosition: 'bottom', // The position of the tooltip. Can be: top, right, bottom and left.
delay: 400, // The delay in msec to show a tooltip.
delayHover: 500, //The delay in msec to prevent quick hover
delayHide: 0, // The delay in msec to hide a tooltip.
hideOnClick: false, // When true, clicking outside of the tooltip will hide it immediately. Works well with keepAlive and delayHide
fadeIn: 200, // The length in msec of the fade in.
fadeOut: 200, // The length in msec of the fade out.
attribute: 'title', // The attribute to fetch the tooltip text if the option content is false.
content: false, // HTML or String or Function (that returns HTML or String) to fill TipTIp with
content: false, // HTML or String or Function (that returns HTML or String) to fill TipTip with
enter: function () { }, // Callback function before a tooltip is shown.
afterEnter: function () { }, // Callback function after a tooltip is shown.
exit: function () { }, // Callback function before a tooltip is hidden.
Expand All @@ -53,12 +60,21 @@
tiptip_arrow = $('#tiptip_arrow');
}

// shared timeout to track delayed hide, because we only have one #tiptip_holder
var timeoutHide = false;

return this.each(function () {
var org_elem = $(this),
data = org_elem.data('tipTip'),
opts = data && data.options || $.extend({}, defaults, options),
callback_data = { holder: tiptip_holder, content: tiptip_content, arrow: tiptip_arrow, options: opts };

// caching and removing the opts.attribute, to prevent browser from showing native tooltip
if (!opts.content && !$.isFunction(opts.content)) {
opts.content = org_elem.attr(opts.attribute);
org_elem.removeAttr(opts.attribute); //remove original attribute
}

if (data) {
switch (options) {
case 'show':
Expand All @@ -75,44 +91,66 @@
}
} else {
var timeout = false;

var timeoutHover = false;
org_elem.data('tipTip', { options: opts });

if (opts.activation == 'hover') {
org_elem.bind('mouseenter.tipTip', function () {
active_tiptip();
if (opts.delayHover){
timeoutHover = setTimeout( function(){ active_tiptip() }, opts.delayHover);
}else{
active_tiptip();
}
}).bind('mouseleave.tipTip', function () {
if (!opts.keepAlive) {
deactive_tiptip();
} else {
tiptip_holder.one('mouseleave.tipTip', function () {
if (timeoutHover){
clearTimeout(timeoutHover);
}

if (!opts.keepAlive) {
deactive_tiptip();
});
}
});
} else {
tiptip_holder.one('mouseleave.tipTip', function () {
deactive_tiptip();
});
}
if (opts.hideOnClick) {
deactive_on_click();
}
});
} else if (opts.activation == 'focus') {
org_elem.bind('focus.tipTip', function () {
active_tiptip();
}).bind('blur.tipTip', function () {
deactive_tiptip();
});
deactive_tiptip();
});
} else if (opts.activation == 'click') {
org_elem.bind('click.tipTip', function (e) {
e.preventDefault();
active_tiptip();
return false;
}).bind('mouseleave.tipTip', function () {
if (!opts.keepAlive) {
deactive_tiptip();
} else {
tiptip_holder.one('mouseleave.tipTip', function () {
if (!opts.keepAlive) {
deactive_tiptip();
});
}
});
} else {
tiptip_holder.one('mouseleave.tipTip', function () {
deactive_tiptip();
});
}
deactive_on_click();
});
} else if (opts.activation == 'manual') {
// Nothing to register actually. We decide when to show or hide.
}

// hide tooltip when user clicks anywhere else but on the tooltip element
function deactive_on_click() {
$('html').off('click.tipTip').on('click.tipTip',function(e){
if (tiptip_holder.css('display') == 'block' && !$(e.target).closest('#tiptip_holder').length) {
$('html').off('click.tipTip');
deactive_tiptip(0); // 0 = immediately, overriding delayHide
}
});
}
}

function active_tiptip() {
Expand Down Expand Up @@ -146,6 +184,11 @@
clearTimeout(timeout);
}

// Kill delayed timeout
if (timeoutHide) {
clearTimeout(timeoutHide);
}

timeout = setTimeout(function () {
tiptip_holder.stop(true, true).fadeIn(opts.fadeIn);
}, opts.delay);
Expand All @@ -157,7 +200,7 @@
opts.afterEnter.call(org_elem, callback_data);
}

function deactive_tiptip() {
function deactive_tiptip(delay) {
if (opts.exit.call(org_elem, callback_data) === false) {
return;
}
Expand All @@ -166,13 +209,47 @@
clearTimeout(timeout);
}

tiptip_holder.fadeOut(opts.fadeOut);
function hide_tiptip() {
tiptip_holder.fadeOut(opts.fadeOut, function(){
// reset tip position and dimensions
$(this).css({ left: '', top: '', height: '', width: '' });
});
}

// Visually hide the tooltip after an optional delay
var delay = (delay !== undefined) ? delay : opts.delayHide;

if (delay == 0) {
hide_tiptip();
// if user clicked, let's also cancel any delayed hide
if (opts.delayHide > 0) {
clearTimeout(timeoutHide);
}
} else {

// don't hide tooltip when we hover it
tiptip_holder.one('mouseenter.tipTip', function() {
clearTimeout(timeoutHide);
tiptip_holder.on('mouseleave.tipTip', function() {
deactive_tiptip();
});
});

timeoutHide = setTimeout(function() {
hide_tiptip();
}, delay);

}

// These should happen whether the tooltip is visually hidden or just moved by active_tiptip()
setTimeout(function() {
$(window).unbind('resize.tipTip scroll.tipTip');

$(window).unbind('resize.tipTip scroll.tipTip');
org_elem.removeClass('tiptip_visible');

org_elem.removeClass('tiptip_visible');
opts.afterExit.call(org_elem, callback_data);
}, delay);

opts.afterExit.call(org_elem, callback_data);
}

function position_tiptip() {
Expand Down Expand Up @@ -206,7 +283,7 @@

function moveBottom() {
tip_class = tip_classes.bottom;
tip_top = org_top + org_height + opts.edgeOffset + (arrow_height / 2);
tip_top = org_top + org_height + opts.edgeOffset;
tip_left = org_left + ((org_width - tip_width) / 2);
}

Expand All @@ -219,7 +296,7 @@
function moveRight() {
tip_class = tip_classes.right;
tip_top = org_top + ((org_height - tip_height) / 2);
tip_left = org_left + org_width + opts.edgeOffset + (arrow_width / 2);
tip_left = org_left + org_width + opts.edgeOffset;
}

// Calculate the position of the tooltip.
Expand Down Expand Up @@ -257,18 +334,18 @@
// Fix the vertical position if the tooltip is off the top or bottom sides of the window's viewport.
if (tip_class == tip_classes.left || tip_class == tip_classes.right) { // If positioned left or right check if the tooltip is off the top or bottom window's viewport.
if (tip_top + tip_height > win_height + win_top) { // If the bottom edge of the tooltip is off the bottom side of the window's viewport.
tip_top = org_top + org_height > win_height + win_top ? org_top + org_height - tip_height : win_height + win_top - tip_height; // Make 'bottom edge of the tooltip' == 'bottom side of the window's viewport'.
tip_top = org_top + org_height > win_height + win_top ? org_top + org_height - tip_height : win_height + win_top - tip_height - 4; // Make 'bottom edge of the tooltip' == 'bottom side of the window's viewport'.
} else if (tip_top < win_top) { // If the top edge of the tooltip if off the top side of the window's viewport.
tip_top = org_top < win_top ? org_top : win_top; // Make 'top edge of the tooltip' == 'top side of the window's viewport'.
tip_top = org_top < win_top ? org_top : win_top + 4; // Make 'top edge of the tooltip' == 'top side of the window's viewport'.
}
}

// Fix the horizontal position if the tooltip is off the right or left sides of the window's viewport.
if (tip_class == tip_classes.top || tip_class == tip_classes.bottom) {
if (tip_left + tip_width > win_width + win_left) { // If the right edge of the tooltip is off the right side of the window's viewport.
tip_left = org_left + org_width > win_width + win_left ? org_left + org_width - tip_width : win_width + win_left - tip_width; // Make 'right edge of the tooltip' == 'right side of the window's viewport'.
tip_left = org_left + org_width > win_width + win_left ? org_left + org_width - tip_width : win_width + win_left - tip_width - 4; // Make 'right edge of the tooltip' == 'right side of the window's viewport'.
} else if (tip_left < win_left) { // If the left edge of the tooltip if off the left side of the window's viewport.
tip_left = org_left < win_left ? org_left : win_left; // Make 'left edge of the tooltip' == 'left side of the window's viewport'.
tip_left = org_left < win_left ? org_left : win_left + 4; // Make 'left edge of the tooltip' == 'left side of the window's viewport'.
}
}

Expand All @@ -286,14 +363,14 @@
arrow_top = tip_height; // Position the arrow vertically on the top of the tooltip.
arrow_left = org_left - tip_left + ((org_width - arrow_width) / 2); // Center the arrow horizontally on the center of the target element.
} else if (tip_class == tip_classes.bottom) {
arrow_top = -arrow_height; // Position the arrow vertically on the bottom of the tooltip.
arrow_top = 0; // Position the arrow vertically on the bottom of the tooltip.
arrow_left = org_left - tip_left + ((org_width - arrow_width) / 2); // Center the arrow horizontally on the center of the target element.
} else if (tip_class == tip_classes.left) {
arrow_top = org_top - tip_top + ((org_height - arrow_height) / 2); // Center the arrow vertically on the center of the target element.
arrow_left = tip_width; // Position the arrow vertically on the left of the tooltip.
} else if (tip_class == tip_classes.right) {
arrow_top = org_top - tip_top + ((org_height - arrow_height) / 2); // Center the arrow vertically on the center of the target element.
arrow_left = -arrow_width; // Position the arrow vertically on the right of the tooltip.
arrow_left = 0; // Position the arrow vertically on the right of the tooltip.
}

tiptip_arrow
Expand Down
Loading