简体   繁体   English

jQuery:使用Plugin Tipsy将工具提示附加到鼠标光标位置

[英]jQuery: Attach Tooltip to Mouse Cursor Position Using Plugin Tipsy

I've been using an old jQuery plugin called Tipsy . 我一直在使用一个名为Tipsy的旧jQuery插件。 I like the way the tooltips look and for the most part I like the plugin. 我喜欢工具提示的外观,而且大多数情况下我都喜欢这个插件。 Unfortunately it only shows tooltips relative to the element it is retrieving the tooltip from. 不幸的是,它只显示相对于它从中检索工具提示的元素的工具提示。 I'd like to show the tooltip in the position of the mouse cursor instead. 我想将工具提示显示在鼠标光标的位置。 Is there any way to do this? 有没有办法做到这一点? I would personally like to use this tooltip plugin if at all possible. 我个人希望尽可能使用这个工具提示插件。

I have tried playing with the plugin for a little while, but the code is beyond my current knowledge of jQuery. 我尝试过使用插件一段时间,但代码超出了我目前对jQuery的了解。 I thought trying to capture the event when firing the 'show' function would let me get the coordinates where the event was fired but that didn't work. 我想在触发'show'函数时尝试捕获事件会让我得到事件被触发的坐标但是没有用。 Any help would be greatly appreciated. 任何帮助将不胜感激。 I'll show the source JS file below: 我将在下面显示源JS文件:

// 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 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';
        this[binder](eventIn, enter)[binder](eventOut, leave);
    }

    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'
};

// 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);

I did not knew tipsy before, and could not find a place where a full package was downloadable. 之前我不知道,并且找不到可以下载完整包的地方。 So took your code and found the CSS from the website, along with the arrow glyph to produce this demo -> http://jsfiddle.net/df108obx/ 所以拿了你的代码,从网站上找到了CSS,以及箭头字形来制作这个演示 - > http://jsfiddle.net/df108obx/

I have made //ANSWER comments anywhere some code is added. 在任何添加了代码的地方,我都会发出//ANSWER注释。 I thought the best approach was to create a new gravity style " x ", that places the tooltip with base from where the mouse was, when the tipsy is activated. 我认为最好的方法是创建一个新的gravity样式“ x ”,当激活tipsy时,将工具提示放在鼠标所在的位置。 So 所以

  1. Added a mouse : {x: 0, y: 0} object to default options mouse : {x: 0, y: 0}对象添加到默认选项
  2. Now storing (e) mouse position in the enter() function 现在将(e)鼠标位置存储在enter()函数中
  3. Added a case 'x' : in the gravity switch in the show() function 添加了一个case 'x' :show()函数的重力开关中

There is certainly room for improvement, but this may be a good skeleton for extending tipsy with new ways of showing itself. 肯定有改进的余地,但这可能是一个很好的骨架,可以用新的方式展示自己。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM