KokoroSenshi (talk | contribs) m (Added comments and further various formatting/refactoring) |
KokoroSenshi (talk | contribs) m (Replaced netbarHeight with bodyMarginTop) |
||
Line 26: | Line 26: | ||
var display_tooltip = function() { |
var display_tooltip = function() { |
||
− | // |
+ | // Body properties (to which the tooltip is appended) |
− | var |
+ | var bodyMarginTop = parseFloat($("body").css("margin-top")); |
// Window properties |
// Window properties |
||
var windowWidth = $(window).width(); |
var windowWidth = $(window).width(); |
||
Line 49: | Line 49: | ||
/** Calculate default positions for tooltip (i.e. centered above the element) */ |
/** Calculate default positions for tooltip (i.e. centered above the element) */ |
||
var pos_left = thisLeft + 0.5*thisWidth - 0.5*tooltipWidth |
var pos_left = thisLeft + 0.5*thisWidth - 0.5*tooltipWidth |
||
− | , pos_top = thisTop - tooltipHeight - |
+ | , pos_top = thisTop - tooltipHeight - bodyMarginTop |
, screen_pos_left = thisScreenPos.left + 0.5*thisWidth - 0.5*tooltipWidth |
, screen_pos_left = thisScreenPos.left + 0.5*thisWidth - 0.5*tooltipWidth |
||
, screen_pos_right = screen_pos_left + tooltipWidth |
, screen_pos_right = screen_pos_left + tooltipWidth |
||
Line 68: | Line 68: | ||
if (screen_pos_top < 0) { |
if (screen_pos_top < 0) { |
||
//tooltip appears below element |
//tooltip appears below element |
||
− | pos_top = thisTop + thisHeight - |
+ | pos_top = thisTop + thisHeight - bodyMarginTop; |
$tooltip.addClass("RTflipped"); |
$tooltip.addClass("RTflipped"); |
||
} |
} |
Revision as of 11:32, 22 April 2018
// Original by Osvaldas Valutis: http://web.archive.org/web/20180306004159/https://osvaldas.info/elegant-css-and-jquery-tooltip-responsive-mobile-friendly
$(function() {
$(".explain, .tooltip").bind("mouseenter", function() {
var $this = $(this)
, tipText = $this.attr("title");
/** Do nothing if no tooltip text */
if (!tipText || tipText === "") return false;
/** Remove the title text since the tooltip will replace it */
$this.removeAttr("title");
/** Initialise and append the tooltip to page while hidden */
var $tooltipText = $('<li style="padding: 10px 8px">' + tipText + '</li>')
, $tooltipCaret = $('<li style="margin: auto; margin-top: -2px;"></li>')
, $tooltip = $('<ul id="tooltip" class="referencetooltip"></ul>')
.append($tooltipText)
.append($tooltipCaret)
.css("opacity", 0)
.appendTo("body");
/** Function to update the tooltip dimensions and properties then display it */
var display_tooltip = function() {
// Body properties (to which the tooltip is appended)
var bodyMarginTop = parseFloat($("body").css("margin-top"));
// Window properties
var windowWidth = $(window).width();
// Text element properties (the element that has the tooltip)
var thisWidth = $this.outerWidth()
, thisHeight = $this.outerHeight()
, thisTop = $this.offset().top
, thisLeft = $this.offset().left
, thisScreenPos = $this[0].getBoundingClientRect();
// Tooltip properties
var tooltipHeight = $tooltip.outerHeight()
, tooltipWidth = $tooltip.outerWidth()
, caretWidth = 14 //TODO: Magic number: The width of the referenceTooltips caret, from inspection
, caretMarginLeft = 0.5*(tooltipWidth - caretWidth); //TODO: Issue with half-pixels rounding;
/** Apply max-width to tooltip then update tooltipWidth */
tooltipWidth = $tooltip
.css("max-width", (windowWidth < 1.5*tooltipWidth) ? 0.5*windowWidth : 340 ) //TODO: 1.5 and 340 need justification and are magic numbers
.outerWidth()
/** Calculate default positions for tooltip (i.e. centered above the element) */
var pos_left = thisLeft + 0.5*thisWidth - 0.5*tooltipWidth
, pos_top = thisTop - tooltipHeight - bodyMarginTop
, screen_pos_left = thisScreenPos.left + 0.5*thisWidth - 0.5*tooltipWidth
, screen_pos_right = screen_pos_left + tooltipWidth
, screen_pos_top = thisScreenPos.top - tooltipHeight
, caret_margin_left = caretMarginLeft;
/** Update horizontal position variables if it will stick off the screen */
// TODO: Currently assumes the tooltip fits screen horizontally
if (screen_pos_left < 0) {
pos_left += (-screen_pos_left);
caret_margin_left -= (-screen_pos_left);
} else if (screen_pos_right > windowWidth) {
pos_left -= (screen_pos_right - windowWidth);
caret_margin_left += (screen_pos_right - windowWidth);
}
/** Update vertical position variables if it will stick off the screen */
if (screen_pos_top < 0) {
//tooltip appears below element
pos_top = thisTop + thisHeight - bodyMarginTop;
$tooltip.addClass("RTflipped");
}
/** Reposition the tooltip */
$tooltip.css( { 'left': pos_left, 'top': pos_top } );
$tooltipCaret.css("margin-left", caret_margin_left); //TODO: Note that this will override the initial "margin: auto"
/** Display the tooltip */
$tooltip.animate({ opacity: 1 }, 100);
};
/** Function to remove the tooltip */
var remove_tooltip = function() {
$tooltip.animate({ opacity: 0 }, 100, function() {
$(this).remove();
});
$this.attr("title", tipText);
};
/** Display the tooltip for the first time */
display_tooltip();
/** Events on which to update the tooltip */
$(window).resize(display_tooltip);
/** Events on which to remove the tooltip*/
$this.bind("mouseleave", remove_tooltip);
$tooltip.bind("click", remove_tooltip);
});
});