Как правильно разместить всплывающую подсказку рядом с частично скрытым изображением

У меня есть следующая страница с использованием всплывающей подсказки, которую я не могу правильно расположить Страница имеет следующие характеристики:

  • #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 I​S LOST the pon̷y he comes he c̶̮omes he comes the ich​or permeates all MY FACE MY FACE ᵒh god no NO NOO̼O​O NΘ stop the an​*̶͑̾̾​̅ͫ͏̙̤g͇̫͛͆̾ͫ̑͆l͖͉̗̩̳̟̍ͫͥͨe̠̅s ͎a̧͈͖r̽̾̈́͒͑e n​ot 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 I​S LOST the pon̷y he comes he c̶̮omes he comes the ich​or permeates all MY FACE MY FACE ᵒh god no NO NOO̼O​O NΘ stop the an​*̶͑̾̾​̅ͫ͏̙̤g͇̫͛͆̾ͫ̑͆l͖͉̗̩̳̟̍ͫͥͨe̠̅s ͎a̧͈͖r̽̾̈́͒͑e n​ot 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; }
Другие вопросы по тегам