Make a jQuery Tipsy tooltip with your mouse

I am sure it is possible - and probably very easy, but I cannot figure out how to make it work. How can I make a Tipsy tooltip horizontally with the mouse?

When hovering over a tooltip-supporting element, I want the tooltip to display in its normal position Y (directly above the element), but instead of fixing the X position in the center of the element, I want it to be equal to the mouse position X To complicate things a bit, I try to enable the mousemove function ONLY for elements with a gravity of 2 characters ("nw", "ne", "sw", "se").

There is no code to publish, because everything I tried does not work, and the plugin is available to the public.

+4
source share
1 answer

Note. Advice will not fully follow the mouse. It will follow the corresponding edge of the element to which the tip is applied.

If you want the tooltip to follow the mouse where it is actually located on the display, you should consider using another plugin.


How to use:

$('.element').tipsy({follow: 'x'}); $('.element').tipsy({follow: 'y'}); 

Plugin itself (requires more testing)

 // tipsy, facebook style tooltips for jquery // version 1.0.0a // (c) 2008-2010 jason frame [ jason@onehackoranother.com ] // releated under the MIT license (function($) { function fixTitle($ele) { if ($ele.attr('title') || typeof($ele.attr('original-title')) != 'string') { $ele.attr('original-title', $ele.attr('title') || '').removeAttr('title'); } } function Tipsy(element, options) { this.$element = $(element); this.options = options; this.enabled = true; fixTitle(this.$element); } Tipsy.prototype = { show: function() { var title = this.getTitle(); if (title && this.enabled) { var $tip = this.tip(); $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body); var pos = $.extend({}, this.$element.offset(), { width: this.$element[0].offsetWidth, height: this.$element[0].offsetHeight }); var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight; var gravity = (typeof this.options.gravity == 'function') ? this.options.gravity.call(this.$element[0]) : this.options.gravity; var tp; switch (gravity.charAt(0)) { case 'n': tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; break; case 's': tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; break; case 'e': tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}; break; case 'w': tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}; break; } if (gravity.length == 2) { if (gravity.charAt(1) == 'w') { tp.left = pos.left + pos.width / 2 - 15; } else { tp.left = pos.left + pos.width / 2 - actualWidth + 15; } } $tip.css(tp).addClass('tipsy-' + gravity); if (this.options.fade) { $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}); } else { $tip.css({visibility: 'visible', opacity: this.options.opacity}); } } }, hide: function() { if (this.options.fade) { this.tip().stop().fadeOut(function() { $(this).remove(); }); } else { this.tip().remove(); } }, getTitle: function() { var title, $e = this.$element, o = this.options; fixTitle($e); var title, o = this.options; if (typeof o.title == 'string') { title = $e.attr(o.title == 'title' ? 'original-title' : o.title); } else if (typeof o.title == 'function') { title = o.title.call($e[0]); } title = ('' + title).replace(/(^\s*|\s*$)/, ""); return title || o.fallback; }, tip: function() { if (!this.$tip) { this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"/></div>'); } return this.$tip; }, validate: function() { if (!this.$element[0].parentNode) { this.hide(); this.$element = null; this.options = null; } }, enable: function() { this.enabled = true; }, disable: function() { this.enabled = false; }, toggleEnabled: function() { this.enabled = !this.enabled; } }; $.fn.tipsy = function(options) { if (options === true) { return this.data('tipsy'); } else if (typeof options == 'string') { return this.data('tipsy')[options](); } options = $.extend({}, $.fn.tipsy.defaults, options); function get(ele) { var tipsy = $.data(ele, 'tipsy'); if (!tipsy) { tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options)); $.data(ele, 'tipsy', tipsy); } return tipsy; } function enter() { var tipsy = get(this); tipsy.hoverState = 'in'; if (options.delayIn == 0) { tipsy.show(); } else { setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn); } }; function move(event) { var tipsy = get(this); tipsy.hoverState = 'in'; if (options.follow == 'x') { var arrow = $(tipsy.$tip).children('.tipsy-arrow'); if (/^[^w]w$/.test(options.gravity) && arrow.position() != null) { var x = event.pageX - ($(arrow).position().left+($(arrow).outerWidth()/2)); } else if (/^[^e]e$/.test(options.gravity) && arrow.position() != null) { var x = event.pageX - ($(arrow).position().left+($(arrow).outerWidth()/2)); } else { var x = event.pageX - ($(tipsy.$tip).outerWidth()/2); } $(tipsy.$tip).css('left', x); } else if (options.follow == 'y') { if (/^w|^e/.test(options.gravity) ) { $(tipsy.$tip).css('top', event.pageY-($(tipsy.$tip).outerHeight()/2)); } } } function leave() { var tipsy = get(this); tipsy.hoverState = 'out'; if (options.delayOut == 0) { tipsy.hide(); } else { setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut); } }; if (!options.live) this.each(function() { get(this); }); if (options.trigger != 'manual') { var binder = options.live ? 'live' : 'bind', eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus', eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur', eventMove = 'mousemove'; this[binder](eventIn, enter)[binder](eventOut, leave)[binder](eventMove, move); } return this; }; $.fn.tipsy.defaults = { delayIn: 0, delayOut: 0, fade: false, fallback: '', gravity: 'n', html: false, live: false, offset: 0, opacity: 0.8, title: 'title', trigger: 'hover', follow: false, }; // Overwrite this method to provide options on a per-element basis. // For example, you could store the gravity in a 'tipsy-gravity' attribute: // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' }); // (remember - do not modify 'options' in place!) $.fn.tipsy.elementOptions = function(ele, options) { return $.metadata ? $.extend({}, options, $(ele).metadata()) : options; }; $.fn.tipsy.autoNS = function() { return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n'; }; $.fn.tipsy.autoWE = function() { return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w'; }; })(jQuery); 
+3
source

Source: https://habr.com/ru/post/1369301/


All Articles