MediaWiki:Gadget-Tooltips.js: Difference between revisions

From Zelda Wiki, the Zelda encyclopedia
Jump to navigation Jump to search
m (Changed the wording of the comment; replaced space by tab)
(Mainspaced: https://zelda.gamepedia.com/index.php?title=User%3AKokoroSenshi%2Fcommon.js&type=revision&diff=629471&oldid=628352)
Line 1: Line 1:
// Original by Osvaldas Valutis: http://web.archive.org/web/20180306004159/https://osvaldas.info/elegant-css-and-jquery-tooltip-responsive-mobile-friendly
// Original by Osvaldas Valutis: http://web.archive.org/web/20180306004159/https://osvaldas.info/elegant-css-and-jquery-tooltip-responsive-mobile-friendly


$( function()
$(function() {
{
var targets = $( '.explain, .tooltip' ),
$(".explain, .tooltip").bind("mouseenter", function() {
target = false,
tooltip = false,
var $this = $(this)
title = false;
  , tipText = $this.attr("title");
 
targets.bind( 'mouseenter', function()
/** Do nothing if no tooltip text */
{
if (!tipText || tipText === "") return false;
target = $( this );
tip = target.attr( 'title' );
/** Remove the title text since the tooltip will replace it */
tooltip = $( '<div id="tooltip"></div>' );
$this.removeAttr("title");
 
if( !tip || tip == '' )
/** Initialise and append the tooltip to page while hidden */
return false;
var $tooltipText = $('<li style="padding: 10px 8px">' + tipText + '</li>')
 
  , $tooltipCaret = $('<li style="margin: auto; margin-top: -2px;"></li>')
target.removeAttr( 'title' );
  , $tooltip = $('<ul id="tooltip" class="referencetooltip"></ul>')
tooltip.css( 'opacity', 0 )
.append($tooltipText)
  .html( tip )
.append($tooltipCaret)
  .appendTo( 'body' );
.css("opacity", 0)
 
.appendTo("body");
var init_tooltip = function()
{
/** Function to update the tooltip dimensions and properties then display it */
if( $( window ).width() < tooltip.outerWidth() * 1.5 )
var display_tooltip = function() {
tooltip.css( 'max-width', $( window ).width() / 2 );
else
// Body properties (to which the tooltip is appended)
tooltip.css( 'max-width', 340 );
var bodyMarginTop = parseFloat($("body").css("margin-top"));
 
// Window properties
var pos_left = target.offset().left + ( target.outerWidth() / 2 ) - ( tooltip.outerWidth() / 2 ),
var windowWidth = $(window).width();
pos_top = target.offset().top - tooltip.outerHeight() - 20 - $('#netbar').height();
// Text element properties (the element that has the tooltip)
 
var thisWidth  = $this.outerWidth()
if( pos_left < 0 )
  , thisHeight = $this.outerHeight()
{
  , thisTop  = $this.offset().top
pos_left = target.offset().left + target.outerWidth() / 2 - 20;
  , thisLeft = $this.offset().left
tooltip.addClass( '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);
}
}
else
tooltip.removeClass( 'left' );
/** Update vertical position variables if it will stick off the screen */
 
if (screen_pos_top < 0) {
if( pos_left + tooltip.outerWidth() > $( window ).width() )
//tooltip appears below element
{
pos_top = thisTop + thisHeight - bodyMarginTop;
pos_left = target.offset().left - tooltip.outerWidth() + target.outerWidth() / 2 + 20;
$tooltip.addClass("RTflipped");
tooltip.addClass( 'right' );
}
}
else
tooltip.removeClass( 'right' );
/** Reposition the tooltip */
 
$tooltip.css( { 'left': pos_left, 'top': pos_top } );
if( pos_top < 0 )
$tooltipCaret.css("margin-left", caret_margin_left); //TODO: Note that this will override the initial "margin: auto"
{
var pos_top = target.offset().top + target.outerHeight();
/** Display the tooltip */
tooltip.addClass( 'top' );
$tooltip.animate({ opacity: 1 }, 100);
}
else
tooltip.removeClass( 'top' );
 
tooltip.css( { left: pos_left, top: pos_top } )
  .animate( { top: '+=10', opacity: 1 }, 50 );
};
};
 
/** Function to remove the tooltip */
init_tooltip();
var remove_tooltip = function() {
$( window ).resize( init_tooltip );
$tooltip.animate({ opacity: 0 }, 100, function() {
 
$(this).remove();
var remove_tooltip = function()
{
tooltip.animate( { top: '-=10', opacity: 0 }, 50, function()
{
$( this ).remove();
});
});
 
$this.attr("title", tipText);
target.attr( 'title', tip );
};
};
 
target.bind( 'mouseleave', remove_tooltip );
/** Display the tooltip for the first time */
tooltip.bind( 'click', remove_tooltip );
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);
});
});
});
});

Revision as of 14:15, 25 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);
		
	});
	
});