我需要一些javascript工具提示的帮助。我下面的代码在悬停时工作得很好,但是我不能将函数放在外面,所以可以通过单击调用它。在函数中,只有用于计算工具提示位置及其显示方式的东西,并且可以正常工作。
非常感谢你的帮助。
var targets = $( '[rel~=tooltip]' ),
target = false,
tooltip = false,
title = false;
targets.on( 'mouseenter', function()
{
target = $( this );
tip = target.attr( 'title' );
tooltip = $( '<div id="tooltip"></div>' );
if( !tip ) {
return false;
}
target.removeAttr( 'title' );
tooltip.css( 'opacity', 0 )
.html( tip )
.appendTo( 'body' );
var init_tooltip = function()
{
containerList = $('.container').find('.listImages');
if( containerList.width() < tooltip.outerWidth() * 1.5 )
tooltip.css( 'max-width', containerList.width() / 2);
else
tooltip.css( 'max-width', 340 );
var pos_left = target.offset().left + ( target.outerWidth() / 2 ) - ( tooltip.outerWidth() / 2 ),
pos_top = target.offset().top + target.outerHeight(),
pos_right = target.offset().right + ( target.outerWidth() / 2 ) - ( tooltip.outerWidth() / 2 );
console.log(pos_right)
if( pos_left < containerList.offset().left )
{
pos_left = target.offset().left;
tooltip.addClass( 'left' );
}
else {
tooltip.removeClass( 'left' );
}
if( pos_left + tooltip.outerWidth() > containerList.offset().left + containerList.width() )
{
pos_left = target.offset().left - tooltip.outerWidth() + target.outerWidth();
tooltip.addClass( 'right' );
}
else {
tooltip.removeClass( 'right' );
}
if( pos_top < 0 )
{
var pos_top = target.offset().top + target.outerHeight();
tooltip.addClass( 'top' );
}
else {
tooltip.removeClass( 'top' );
}
tooltip.css( { left: pos_left, top: pos_top } )
.animate( { top: '+=10', opacity: 1 }, 50 );
};
init_tooltip();
$( window ).resize( init_tooltip );
var remove_tooltip = function()
{
tooltip.animate( { top: '-=10', opacity: 0 }, 50, function()
{
$( this ).remove();
});
target.attr( 'title', tip );
};
target.bind( 'mouseleave', remove_tooltip );
});
答案 0 :(得分:0)
我根据您在问题中提供的内容创建了一个小提琴:http://jsfiddle.net/R26Ba/1/
但是,因为我没有完整的页面实现,所以它基于理论而不是实际可以在小提琴中使用。
基本上我所做的是创建一个Tooltip对象:
function Tooltip(el) {
//...
}
其中包含原型方法create
,position
和destroy
。然后创建了基于mouseevents创建和销毁工具提示的自定义绑定:
$('[rel~=tooltip][title]').on({
'tooltip.create': function() {
$(this).trigger('tooltip.destroy');
activeTooltip = new Tooltip(this);
},
'tooltip.destroy': function() {
if(activeTooltip) {
activeTooltip.destroy();
}
},
'mouseenter': function() {
$(this).trigger('tooltip.create');
},
'mouseleave': function() {
$(this).trigger('tooltip.destroy');
},
'click': function(e) {
e.stopPropagation();
if(activeTooltip && activeTooltip.el == this) {
$(this).trigger('tooltip.destroy');
} else {
$(this).trigger('tooltip.create');
}
}
});
$(document.body).on('click', function() {
if(activeToolTip) {
activeTooltip.destroy();
}
});
$(window).on('resize', function() {
if(activeTooltip) {
activeTooltip.position();
}
});
另外,附注:您可能会注意到我清理了很多outerWidth/Height
和offset
来电。这些功能可以非常昂贵(性能明智)来调用,所以你真的想留意你必须使用它们的次数。
附注2:您可能还想为jQuery使用resizeEnd
事件插件。这将限制对position
方法的调用量,并将提升整体性能。
旁注3:我现在正在嘲笑自己,因为我接受了这个努力然后才意识到......你如何点击一个元素而不用导致mouseenter
火灾事件?
答案 1 :(得分:0)
如果要重用init_tooltip函数,可以在mouseenter事件之外声明它,并传递两个参数:target和tooltip。
init_tooltip函数定义如下:
var init_tooltip = function(target, tooltip)
然后在您的mouseenter事件中,您将拥有:
init_tooltip(target, tooltip);
$( window ).resize( function () { init_tooltip(target, tooltip); } );
这样,您也可以将它用于click事件处理程序,如下所示:
targets.on('click', function () {
tooltip = $( '<div id="tooltip"></div>' );
init_tooltip($(this), tooltip);
});
您可能需要在点击事件中重现您的逻辑,以确定它是否应显示或隐藏工具提示。
答案 2 :(得分:0)
这就是我现在可以做的事情,但是点击和鼠标移动再次出现问题。我改进了代码,但这并不完美。
$( "body" ).append( '<div id="tooltip"></div>' );
var activeTooltip = null,
$tooltip = $('#tooltip'),
$containerList = $('#content .listImages');
function Tooltip(el) {
this.el = el;
this.$el = $(el);
this.text = this.$el.attr('data-content');
this.create();
}
$.extend(Tooltip.prototype, {
'create': function () {
this.$el.removeAttr('data-content');
$tooltip.css({
'opacity': 0
}).text(this.text);
this.position();
},
'position': function () {
var conWidth = $containerList.width(),
conOffset = $containerList.offset(),
toolWidth = $tooltip.outerWidth();
if (conWidth < $tooltip.outerWidth() * 1.5) {
$tooltip.css('max-width', conWidth / 2);
} else {
$tooltip.css('max-width', 340);
}
var elOffset = this.$el.offset(),
elWidth = this.$el.outerWidth(),
elHeight = this.$el.outerHeight(),
pos_left = elOffset.left + (elWidth / 2) - (toolWidth / 2),
pos_top = elOffset.top + elHeight;
if (this.$el.offset().left + (elWidth / 2) - ($tooltip.outerWidth() / 2) < conOffset.left) {
pos_left = this.$el.offset().left;
$tooltip.addClass('left');
} else {
$tooltip.removeClass('left');
}
if (elOffset.left + (this.$el.outerWidth() / 2) - ($tooltip.outerWidth() / 2) + $tooltip.outerWidth() > $containerList.offset().left + $containerList.width()) {
pos_left = this.$el.offset().left - $tooltip.outerWidth() + this.$el.outerWidth();
$tooltip.addClass('right');
} else {
$tooltip.removeClass('right');
}
if (elOffset.top + this.$el.outerHeight() < 0) {
pos_top = elOffset.top + this.$el.outerHeight();
$tooltip.addClass('top');
} else {
$tooltip.removeClass('top');
}
$tooltip.css({
'left': pos_left,
'top': pos_top
})
.animate({
'top': '+=10',
'opacity': 1
}, 50);
},
'destroy': function () {
$tooltip.animate({
'top': '-=10',
'opacity': 0
}, 50);
this.$el.attr('data-content', this.text);
activeTooltip = null;
}
});
var savelastTooltip, activeSaveTooltip = false;
$('[rel~=tooltip][data-content]').on({
'tooltip.create': function () {
$(this).trigger('tooltip.destroy');
activeTooltip = new Tooltip(this);
},
'tooltip.destroy': function () {
if (activeTooltip) {
activeTooltip.destroy();
}
},
'mouseenter': function () {
$(this).trigger('tooltip.create');
},
'mouseleave': function () {
$(this).trigger('tooltip.destroy');
if(true === activeSaveTooltip)
{
activeTooltip = new Tooltip(savelastTooltip);
}
},
'click': function (e) {
e.stopPropagation();
activeSaveTooltip = true;
savelastTooltip = this;
if (activeTooltip && activeTooltip.el != this) {
$(this).trigger('tooltip.destroy');
} else if(activeTooltip && activeTooltip.el == this) {
$(this).off('mouseleave');
} else {
$(this).trigger('tooltip.create');
}
}
});
$(window).on('resize', function () {
if (activeTooltip) {
activeTooltip.position();
}
});