Как ограничить размер DIV в стиле всплывающей подсказки / всплывающего окна, чтобы он не запускал полосы прокрутки на странице

Мышь наводит курсор на элемент, и появляется подсказка. Подсказка переполняет страницу, вызывая полосу прокрутки, которая меняет макет ровно настолько, чтобы базовый элемент, вызвавший подсказку, больше не находился под указателем мыши, поэтому подсказка исчезает.

Кончик уходит, полоса прокрутки уходит, и теперь мышь снова находится над элементом.

Смыть, прополоскать, повторить.

Если бы я мог убедиться, что эта подсказка не слишком велика, чтобы запускать полосы прокрутки, это решило бы мою проблему.

Обновлено: после прочтения комментариев нужно уточнить некоторые вещи: Div содержит текст, который может быть разным. Если можно, я хочу показать весь текст. Расположение div должно быть рядом с элементом, на котором кончик мыши закончился. Итак, ключ в том, что мне нужно знать, нужно ли обрезать текст.

Я нашел эту ссылку:
http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
который содержит эту часть головоломки, выясняя, насколько велико окно браузера:

function alertSize() {
  var myWidth = 0, myHeight = 0;
  if ( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if ( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if ( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  window.alert( 'Width = ' + myWidth );
  window.alert( 'Height = ' + myHeight );
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
0
4 091
9

Ответы 9

редактировать: в ответ на комментарии, похоже, вы пытаетесь отобразить всплывающую подсказку, не влияя на позиционирование существующих элементов (и, таким образом, вызывая полосу прокрутки в главном окне).

если это так, вы хотите определить позицию всплывающей подсказки как абсолютную, так как это удалит ее из потока элементов (поэтому, когда она появится, она не подтолкнет остальную часть страницы вниз).

например, вы можете запустить его скрытым:

#tooltip {
  position: absolute;
  height: 100px;
  width: 200px;
  border: 1px solid #444444;
  background-color: #EEEEEE;
  display: none;
}

затем, при наведении курсора мыши (или как там оно называется), установите css top и left в #tooltip в нужное вам положение и переключите отображение на block. поскольку он расположен абсолютно, он не будет вызывать мерцания.

CSS: укажите width и height всплывающей подсказки, добавьте к нему overflow: hidden или overflow: scroll.

position: absolute тоже работает нормально, но, конечно, тогда вам нужно будет указать позиции top и left во всплывающей подсказке.

Может быть, я спрашиваю, как мне получить границу экрана, чтобы установить ширину и высоту. (это называется "окном просмотра"?)

Corey Trager 17.10.2008 08:35

ммм .. Я не уверен, что понимаю это. Но тогда, если всплывающая подсказка находится внизу экрана, разве она не станет меньше высоты, чем должна быть? Ваша единственная цель - избежать «мерцания», вызванного появлением всплывающей подсказки, верно?

andyk 17.10.2008 08:43

Моя единственная цель - избежать мерцания, что в данном случае означает не запускать страницу без полос прокрутки, чтобы внезапно получить полосы прокрутки.

Corey Trager 17.10.2008 08:54

Для этого нужно аккуратно расположить всплывающую подсказку. Вы тоже пробовали position: fixed? Таким образом, при правильной настройке всплывающая подсказка будет полностью внутри области просмотра. Если это по-прежнему не помогает, опубликуйте дополнительную информацию и URL-адрес упомянутой страницы.

andyk 17.10.2008 09:23

это также может помочь отредактировать ваше сообщение с некоторым кодом того, где вы сейчас находитесь

Owen 17.10.2008 09:47

Мне кажется, что вам нужно положение курсора в окне браузера клиента. Затем вы можете выполнить свои вычисления, чтобы разместить всплывающую подсказку так, чтобы она не пересекала границу.

В сети я нашел небольшую статью, в которой обсуждается это в разных браузерах: Положение курсора мыши. Может быть, это поможет вам решить вашу проблему?

И дополнительную информацию о размере браузера можно найти в здесь.

Надеюсь, это поможет.

вы можете использовать скрытый DIV, расположенный на 0,0 с шириной и высотой, установленными на 100%, в качестве «критерия» для измерения клиентской области экрана.

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

некоторый код ниже (непроверенный, скопированный из другого проекта и переименованный в встроенный)

var toolTipDiv; //this is your tooltip div element
//call AdjustToolTipPosition(window.event);
function AdjustToolTipPosition(e)
{
    var cpos = getPosition(e);
    mouseX = cpos.x;
    mouseY = cpos.y;

    //Depending on IE/Firefox, find out what 
    //object to use to find mouse position

    toolTipDiv.style.visibility = "visible";

    //backdrop 'yardstick' for client area measurement
    var backdropDiv = document.getElementById("divBackdrop");

    //make sure floating box doesn't leave the screen
    //we know box is 200x200 plus margins, say 215x215
    if ((cpos.y + 215) > backdropDiv.offsetHeight)
    {
        cpos.y = backdropDiv.offsetHeight - 215;
    }
    if ((cpos.x + 215) > backdropDiv.offsetWidth)
    {
        cpos.x = backdropDiv.offsetWidth - 215;
    }
    toolTipDiv.style.left = cpos.x + "px";
    toolTipDiv.style.top = cpos.y + "px";
}
//this function courtesy of 
//http://hartshorne.ca/2006/01/23/javascript_cursor_position/
function getPosition(e) 
{
    e = e || window.event;
    var cursor = {x:0, y:0};
    if (e.pageX || e.pageY) 
    {
        cursor.x = e.pageX;
        cursor.y = e.pageY;
    }
    else 
    {
        var de = document.documentElement;
        var b = document.body;
        cursor.x = e.clientX + 
            (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
        cursor.y = e.clientY + 
            (de.scrollTop || b.scrollTop) - (de.clientTop || 0);
    }
    return cursor;
}

Можно было бы настроить призрачный прозрачный DIV точно для всего размера страницы / окна просмотра. Затем вы можете «прикрепить» к нему всплывающую подсказку DIV, указав атрибут CSS float: right. Это даст вам правильные размеры верхнего / левого угла всплывающей подсказки для окончательного рендеринга всплывающей подсказки.

Обновлено: это следует делать только в случае «крайних ситуаций».

Вы можете попробовать определить, где находится указатель, и, если он находится в правой 1/4 (или любой другой области, которую вы определяете) области просмотра, поместите всплывающую подсказку слева от указателя, в противном случае поместите ее вправо.

Вы упомянули, что текст может быть разным, но неужели он станет очень большим? Может ли он занимать весь экран? Скорее всего, это будет максимальный размер, поэтому примите это во внимание при принятии решения, какой порог использовать, чтобы решить, должен ли наконечник быть справа или слева.

Затем полностью разместите свой блок подсказки и на всякий случай присвойте ему атрибуты max-height и max-width. Если текст действительно становится больше, присвойте ему overflow: scroll в CSS.

У меня была такая же проблема в начале этого года. Как я это исправил:

  1. Я предположил вертикальная прокрутка в порядке, но горизонтальная прокрутка - нет. (Всегда было достаточно места, чтобы вертикальная полоса прокрутки не влияла на мой макет)
  2. Я исправил относительное вертикальное положение всплывающей подсказки относительно цели. (Верх всплывающей подсказки всегда был на 5 пикселей ниже нижней части привязки)
  3. Левая часть всплывающей подсказки была настроена с учетом размера экрана. Если бы вся подсказка могла уместиться на одной строке, круто. В противном случае я ограничил максимальную ширину и обернул ее.

Одна вещь, которая помогла мне реализовать это, была статья Quirksmode Найти позицию.

Мое решение может быть не совсем тем, что вы ищете, но, по крайней мере, взгляните на ссылку Quirksmode, она хороша.

Надеюсь, это поможет!

Лучше всего разместить всплывающую подсказку слева или справа от элемента в зависимости от того, какая сторона страницы ближе. У меня фиксированная ширина всплывающей подсказки, я заполняю ее содержимым и делаю видимым, когда это необходимо, а затем размещаю ее в зависимости от положения мыши. Вот ключевая часть обработчика события onmousemove, когда включена всплывающая подсказка:

if (!e) var e = window.event;
if (e) {
    var posx = 0;
    var posy = 0;

    if (e.pageX || e.pageY) {
        posx = e.pageX;
        posy = e.pageY;
    }
    else if (e.clientX || e.clientY) {
        posx = e.clientX + document.body.scrollLeft
            + document.documentElement.scrollLeft;
        posy = e.clientY + document.body.scrollTop
            + document.documentElement.scrollTop;
    }

    var overflowX = (document.body.clientWidth + document.body.scrollLeft + document.documentElement.scrollLeft) - (posx + 25+ tooltip.clientWidth);
    if (overflowX < 0) posx -= 25+ (tooltip.clientWidth);

    var overflowY = (document.body.clientHeight + document.body.scrollTop + document.documentElement.scrollTop) - (posy + 15+ tooltip.clientHeight);
    if (overflowY < 0) posy += overflowY;

    tooltip.style.left=(10+posx);
    tooltip.style.top=(10+posy);
}

Вот код, который я в итоге использовал, и, похоже, он работает.

function display_popup(s)
{ 

    var popup = document.getElementById("popup");
    popup.innerHTML = s

    //viewport_height = $(document).height()  doesn't work
    viewport_height = get_viewport_size()[1] // does this factor in scrollbar?

    mytop = $(current_element).offset().top + $(current_element).height() + 4
    scroll_offset_y = $(document).scrollTop()
    y_in_viewport = mytop - scroll_offset_y

    if (y_in_viewport < viewport_height) // are we even visible?
    {
        // Display the popup, but truncate it if it overflows   
        // to prevent scrollbar, which shifts element under mouse
        // which leads to flicker...

        popup.style.height= ""
        popup.style.display = "block";

        if (y_in_viewport + popup.offsetHeight > viewport_height)
        {
            overflow = (y_in_viewport + popup.offsetHeight) - viewport_height

            newh = popup.offsetHeight -  overflow
            newh -= 10 // not sure why i need the margin..

            if (newh > 0)
            {
                popup.style.height = newh 
            }
            else
            {
                popup.style.display = "none";
            }
        }
        popup.style.left = $(current_element).offset().left + 40
        popup.style.top = mytop
    }
}


function get_viewport_size()
{
  var myWidth = 0, myHeight = 0;

  if ( typeof( window.innerWidth ) == 'number' )
  {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  }
  else if ( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
  {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  }
  else if ( document.body && ( document.body.clientWidth || document.body.clientHeight ) )
  {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }

  return [myWidth, myHeight];
}

Другие вопросы по теме