Как правильно разместить всплывающую подсказку рядом с частично скрытым изображением
У меня есть следующая страница с использованием всплывающей подсказки, которую я не могу правильно расположить Страница имеет следующие характеристики:
#outer-container
это моя страница Он имеет фиксированную ширину.- Здесь очень много
.inner-container
, Они имеют фиксированную ширину иoverflow-x: auto
, .inner-containers
динамически генерируются. (Не уверен, что это актуально, поэтому следующий пример кода является статическим)- внутри
.inner-container
Divs есть произвольный HTML, который может включать в себя много<img>
теги - каждый
<img>
имеет всплывающую подсказкуalt
текст в качестве заголовка. - Изображения могут быть шире, чем их
.inner-container
ДИВ
Вот фрагмент, вы можете увидеть проблему при запуске фрагмента на полной странице.
$("#outer-container").tooltip({
selector: "img",
placement: "right",
title: function () { return $(this).attr("alt"); },
});
#outer-container
{
border: 1px solid;
padding: 10px;
width: 960px;
margin-left: auto;
margin-right: auto;
overflow: auto;
}
.inner-container
{
width: 600px;
overflow-x: auto;
border: 1px solid;
margin-bottom : 10px;
float: right;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<div id="outer-container">
<div class="inner-container">
<figure>
<img src="http://i.imgur.com/mrXWW8S.png" alt="Man ALL IS LOŚ͖̩͇̗̪̏̈́T ALL IS LOST the pon̷y he comes he c̶̮omes he comes the ichor permeates all MY FACE MY FACE ᵒh god no NO NOO̼OO NΘ stop the an*̶͑̾̾̅ͫ͏̙̤g͇̫͛͆̾ͫ̑͆l͖͉̗̩̳̟̍ͫͥͨe̠̅s ͎a̧͈͖r̽̾̈́͒͑e not rè̑ͧ̌aͨl̘̝̙̃ͤ͂̾̆ ZA̡͊͠͝LGΌ ISͮ̂҉̯͈͕̹̘̱ TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚N̐Y̡ H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ" />
<figcaption>
Image originally posted by <a href="http://meta.stackexchange.com/questions/213769/work-is-hard-lets-color-the-walls/213975#213975">Travis J</a>
</figcaption>
</figure>
</div>
<div class="inner-container">
<figure>
<img src="https://stackru.com/images/91e9cb8240b8da3017c3c432dd810f0c3cf83434.png" alt="Sanely-sized stackru logo" />
<figcaption>Sanely-sized stackru logo</figcaption>
</figure>
</div>
<div class="inner-container">
<figure>
<img src="https://stackru.com/images/a1b8269d32be6ff0bc5a5a3b0f52d27f277f094f.jpg" alt="Insanely-long-sized stackru logo" />
<figcaption>Insanely-long-sized stackru logo</figcaption>
</figure>
</div>
</div>
Приведенный выше код отлично работает, показывая подсказки, но есть небольшая проблема. Всплывающая подсказка появляется не сразу после усеченного изображения, а после места, где заканчивается скрытая часть изображения, поэтому она оказывается слишком далеко от изображения.
Как вы прокручиваете .inner-container
Справа подсказка становится ближе к IMG, пока не будет рядом с ним.
Ситуация становится еще хуже, когда изображение шире, чем весь экран, потому что теперь всплывающая подсказка находится слишком далеко вправо, и теперь она генерирует не только ожидаемую полосу прокрутки в .inner-container
но и один на всю страницу. Теперь всплывающую подсказку невозможно увидеть, потому что, как только вы попытаетесь прокрутить подсказку, она исчезнет.
Теперь вопрос.....
Есть ли способ настроить всплывающую подсказку или стилизовать ее с помощью css, чтобы она всегда отображалась на краю обрезанного изображения, как на втором изображении, в отличие от "фактического", но скрытого края? Также, когда изображение короче, чем .inner-container
подсказка должна появиться рядом с изображением, а не с правого края контейнера
2 ответа
Спасибо @y34h за идею, но мне пришлось рассчитать правильное значение left
свойство, в частности, переопределив фактический JS-код начальной загрузки.
Вот новый Tooltip.getCalcultedOffset
которая является функцией, которая вычисляет абсолютную позицию всплывающей подсказки:
$.fn.tooltip.Constructor.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
return placement === 'bottom' ? {
top: pos.top + pos.height,
left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement === 'top' ? {
top: pos.top - actualHeight,
left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement === 'left' ? {
top: pos.top + pos.height / 2 - actualHeight / 2,
left: pos.left - actualWidth } :
/* placement == 'right' */ {
top: pos.top + pos.height / 2 - actualHeight / 2,
left:
/* begin fix */
Math.min(
pos.left + pos.width, //original left
$(".inner-container").offset().left + $(".inner-container")[0].clientWidth //max left
)
/* end fix */
};
};
Фактическое изменение заключено в /* begin fix */
а также /* end fix */
Вот полный рабочий код:
$.fn.tooltip.Constructor.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
return placement === 'bottom' ? {
top: pos.top + pos.height,
left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement === 'top' ? {
top: pos.top - actualHeight,
left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement === 'left' ? {
top: pos.top + pos.height / 2 - actualHeight / 2,
left: pos.left - actualWidth } :
/* placement == 'right' */ {
top: pos.top + pos.height / 2 - actualHeight / 2,
left:
/* begin fix */
Math.min(
pos.left + pos.width, //original left
$(".inner-container").offset().left + $(".inner-container")[0].clientWidth //max left
)
/* end fix */
};
};
$("#outer-container").tooltip({
selector: "img",
placement: "right",
title: function () { return $(this).attr("alt"); },
});
#outer-container
{
border: 1px solid;
padding: 10px;
width: 960px;
margin-left: auto;
margin-right: auto;
overflow: auto;
}
.inner-container
{
width: 600px;
overflow-x: auto;
border: 1px solid;
margin-bottom : 10px;
float: right;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<div id="outer-container">
<div class="inner-container">
<figure>
<img src="http://i.imgur.com/mrXWW8S.png" alt="Man ALL IS LOŚ͖̩͇̗̪̏̈́T ALL IS LOST the pon̷y he comes he c̶̮omes he comes the ichor permeates all MY FACE MY FACE ᵒh god no NO NOO̼OO NΘ stop the an*̶͑̾̾̅ͫ͏̙̤g͇̫͛͆̾ͫ̑͆l͖͉̗̩̳̟̍ͫͥͨe̠̅s ͎a̧͈͖r̽̾̈́͒͑e not rè̑ͧ̌aͨl̘̝̙̃ͤ͂̾̆ ZA̡͊͠͝LGΌ ISͮ̂҉̯͈͕̹̘̱ TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚N̐Y̡ H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ" />
<figcaption>
Image originally posted by <a href="http://meta.stackexchange.com/questions/213769/work-is-hard-lets-color-the-walls/213975#213975">Travis J</a>
</figcaption>
</figure>
</div>
<div class="inner-container">
<figure>
<img src="https://stackru.com/images/91e9cb8240b8da3017c3c432dd810f0c3cf83434.png" alt="Sanely-sized stackru logo" />
<figcaption>Sanely-sized stackru logo</figcaption>
</figure>
</div>
<div class="inner-container">
<figure>
<img src="https://stackru.com/images/a1b8269d32be6ff0bc5a5a3b0f52d27f277f094f.jpg" alt="Insanely-long-sized stackru logo" />
<figcaption>Insanely-long-sized stackru logo</figcaption>
</figure>
</div>
</div>
#outer-container .tooltip { left: calc(50% + 480px)!important; }