keep an absolutely positioned element in viewport

2019-07-05 06:02发布

问题:

I am working on a site now with a lot of tooltips. I want to ensure that the tooltips will always show up fully in the viewport.

I know there are plugins for tooltips, but they won't work for me because the tooltip-ing is done via css (and I can't go change all of them!). Any element that you want to get a tooltip is given a position:relative, and is immediately followed by an element with class='tooltip' - here is the css code:

.tooltip{
    display:none;
    color: #262626;
    background-color: #FEFEE0;
    padding: 5px 12px;
    position: absolute;
    box-shadow: 0 0 5px #A6A6A6;
    margin-top:-8px;
    z-index: 1000;
}
*:hover + .tooltip {
    display:block ! important;
}
.tooltip:hover{
    display:block;
}

What I would like to do is, every time a tooltip is displayed (or every time the element before the tooltip is hovered), run a function to calculate the offset and make sure it fits in the screen (or move it, if not).

The only thing I can think of now that I didn't try yet is running something like:

$("*:hover").each(function(e){
  if ($(this).next().hasClass('tooltip')
    //run some positioning function
}

Ok, so I'm no jquery expert and could be that the above is buggy, I didn't try it yet, but you get the idea. But does it make sense? Would it impact performance (in a bad way)?

I've spent hours working on this and coming up empty. Any ideas greatly appreciated!

回答1:

There is a far more simple solution to your problem. You can use position:fixed; to position an element according to the viewport. It will only fail in Internet Explorer 7, as far as I know, so if you care about this, you need to use an IE7 trick to simulate fixed positioning. Also, * selectors and what you are doing there will undoubtedly impact on performance. This is a good place to read about CSS and JS profiling. Beware, it is exhaustively detailed, but definitely worth reading.



回答2:

I examined tooltipsy plugin and saw that they are positioning tooltips by the way you mentioned. You can check the samples here.

Define a html element type for tooltips and listen their hover event, instead of listening all elements. So you can set title-content datas in each of the elements, rather than creating a tooltip element for all possible data.

<a href="#" class="see-tooltip" title="Title-1" content="Content-1">Hover Me!</a>

And assign hover event to 'show-tooltip' class.

var $tooltip = $('#tooltip'); //select the early created tooltip element here
$('a.show-tooltip').hover(function() {
   var title = $(this).attr('title');
   var content = $(this).attr('content');
   //set title and content to $tooltip here
   //calculate and set positioning here
   $tooltip.show(); //show tooltip after setting it's new position
}, function() {
    $tooltip.hide(); //hide tooltip when hover ends
);