Zelda Wiki

Want to contribute to this wiki?
Sign up for an account, and get started!

Come join the Zelda Wiki community Discord server!

READ MORE

Zelda Wiki
m (Added comments and further various formatting/refactoring)
m (Replaced netbarHeight with bodyMarginTop)
Line 26: Line 26:
 
var display_tooltip = function() {
 
var display_tooltip = function() {
 
 
// Netbar properties
+
// Body properties (to which the tooltip is appended)
var netbarHeight = $("#netbar").height();
+
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 - netbarHeight
+
, 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 - netbarHeight;
+
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);
		
	});
	
});