I would like to clean up the mouseenter
portion of my tooltip plugin by calling a new function called showKeyTip
. (This would also enable me to use an if statement inside mouseenter to control the hover)
I got the idea from how setTimeout
is handled in mouseleave
, but for some reason, a similar call is not working in mouseenter
...
I feel like I am missing something, or do not fully understand how $(this)
is tied to things.
Any advice/suggestions are appreciated.
Current code (snippet):
// [ hide ]
function hideKeyTip(){
timer = setTimeout(function(){
keyTip.stop().fadeOut(faderate)}, timeout);
}
// [ control ]
return this.each(function(){
$(this)
.on("mouseenter", function(){
clearTimeout(timer);
// dimensions
var targetH = $(this).height()/2,
targetW = $(this).width();
// position
var top = $(this).offset().top - targetH + padtop,
left = $(this).offset().left + targetW + padleft;
// apply css & show
keyTip.css({
'top': top,
'left': left
}).show();
})// mouseenter
.on("mouseleave", function(){
hideKeyTip();
});// mouseleave
});// return this
Cleaned up version (not working)
I moved the contents of mouseenter into a new function called showKeyTip and call it within mouseenter.
// [ hide ]
function hideKeyTip(){
timer = setTimeout(function(){
keyTip.stop().fadeOut(faderate)}, timeout);
}
// [ show ]
function showKeyTip(){
clearTimeout(timer);
// dimensions
var targetH = $(this).height()/2,
targetW = $(this).width();
// position
var top = $(this).offset().top - targetH + padtop,
left = $(this).offset().left + targetW + padleft;
// apply css settings & show
keyTip.css({
'top': top,
'left': left
}).show();
}
// [ control ]
return this.each(function(){
$(this)
.on("mouseenter", function(){
showKeyTip();
})// mouseenter
.on("mouseleave", function(){
hideKeyTip();
});// mouseleave
});// return this
Update: Cleaned up version 2 (working)
Using adeneo's suggestion, there is one last piece to this puzzle...
What is the best way to roll in a test case for hover or mouseenter/over of the tooltip?
I'd like to keep showing the tooltip if being hovered over.
My current stance is to add an if statement to the hideKeyTip function, but the tooltips get hung up on being shown and never fade out when the mouse leaves.
// [ hide ]
function hideKeyTip(){
if(!keyTip.hover()){
timer = setTimeout(function(){
keyTip.stop().fadeOut(faderate)}, timeout);
}
}
// [ show ]
function showKeyTip(){
clearTimeout(timer);
// dimensions
var targetH = $(this).height()/2,
targetW = $(this).width();
// position
var top = $(this).offset().top - targetH + padtop,
left = $(this).offset().left + targetW + padleft;
// apply css settings & show
keyTip.css({
'top': top,
'left': left
}).show();
}
// [ control ]
return this.on({
mouseenter: showKeyTip,
mouseleave: hideKeyTip
});// return this
Update: Hover control (help!)
Trying to reuse the hide and show functions to display the tooltip when the user is hovering over the actual tooltip. (useful for when a link is present in the tooltip.)
Any suggestions? What am I doing wrong? Thanks...
// [ hide ]
function hideKeyTip(){
timer = setTimeout(function(){
keyTip.stop().fadeOut(faderate)}, timeout);
}
// [ show ]
function showKeyTip(){
clearTimeout(timer);
// dimensions
var targetH = $(this).height()/2,
targetW = $(this).width();
// position
var top = $(this).offset().top - targetH + padtop,
left = $(this).offset().left + targetW + padleft;
// apply css settings & show
keyTip.css({
'top': top,
'left': left
}).show();
}
// [ control ]
return this.on({
mouseenter: showKeyTip,
mouseleave: hideKeyTip
});
return keyTip.on({
// note: keyTip = $(settings.tooltip);
mouseenter: function(){
clearTimout(timer);
},
mouseleave: hideKeyTip
});
Final Update: Hover control (solved)
After some trial and error in codepen, I think I've found a good solution for showing the tooltip while the user's mouse cursor was over it. I was also approaching the problem from the wrong angle... is that return keyTip.on() statement even legal?
So here's what I've come up with. If you can point out any negatives to this method, please let me know.
I will post the codepen in a comment below when I have it cleaned up.
Thank you adeneo for pointing me in the right direction.
// [ hide ]
function hideKeyTip(){
// note: keyTip = $(settings.tooltip);
keyTip.on({
mouseenter: function(){
//you have arrived
},
mouseleave: function(){
timer = setTimeout(function(){
keyTip.stop().fadeOut(faderate)}, timeout);
};
});
}
// [ show ]
function showKeyTip(){
clearTimeout(timer);
// dimensions
var targetH = $(this).height()/2,
targetW = $(this).width();
// position
var top = $(this).offset().top - targetH + padtop,
left = $(this).offset().left + targetW + padleft;
// apply css settings & show
keyTip.css({
'top': top,
'left': left
}).show();
}
// [ control ]
return this.on({
mouseenter: showKeyTip,
mouseleave: hideKeyTip
});
When calling the functions in the window scope, the window is obviously the value of
this
.You need to reference the functions, not call them inside other anonymous functions, to keep the value of
this
as the element.note that you can drop the
each
call if all you're doing is callingon
on the collection, as jQuery iterates iternally.