Как в JavaScript, SCSS и HTML создать tooltip, который будет отображаться при наведении курсора на определенный элемент?

Как реализовать компонент tooltip в Thymeleaf, который будет отображаться при наведении на объект, находящийся ниже него, например, на компонент, input, p или svg? В приведённом коде есть некоторые сложности, и я постарался сделать это, но не достиг ожидаемого результата. Вот исходный код: 

<pre><code class="javascript">$('.custom-tooltip').mouseenter(function () {
    const $tooltipText = $(this).find('.tooltip-text');
    const rect = $tooltipText.get(0).getBoundingClientRect();
    const viewportHeight = $(window).height();

    if (rect.top &lt; 0 || rect.bottom &gt; viewportHeight) {
        $tooltipText.addClass('below');
    } else {
        $tooltipText.removeClass('below');
    }

    $(this).mouseleave(function () {
        $(this).find('.tooltip-text').removeClass('below');
    });
});</code></pre> 

И вот как я пытался это реализовать, но у меня не получилось: 

<pre><code class="javascript">$('.custom-tooltip').mouseenter(function () {
    const $tooltipText = $(this).find('.tooltip-text');
    const rect = $tooltipText.get(0).getBoundingClientRect();
    const viewportHeight = $(window).height();

    if (rect.top &lt; 0 || rect.bottom &gt; viewportHeight) {
        $tooltipText.addClass('below');
    } else {
        $tooltipText.removeClass('below');
    }

    $(this).mouseleave(function () {
        $(this).find('.tooltip-text').removeClass('below');
    });
});
$('.custom-tooltip').each(function(){
    const $tooltip = $(this);
    const $elementToBeHoveredOver = $tooltip.next();
    if($elementToBeHoveredOver.length === 0){
        console.error('Tooltips must be next ( have below) element above/below which is hovering!');
    }else if($elementToBeHoveredOver.hasClass('custom-
  • 31 октября 2024 г. 17:03
Ответы на вопрос 2
Создание компонента tooltip, который отображается при наведении курсора на определённый элемент с использованием JavaScript, SCSS и HTML, довольно распространённая задача. Я приведу готовый пример, включая все необходимые компоненты и аннотации. Также покажу, как интегрировать это решение с Thymeleaf. 

### HTML

```html
<div class="tooltip-container">
    <span class="custom-tooltip" data-tooltip="Ваш текст подсказки">Наведи на меня</span>
    <input type="text" placeholder="Поле ввода" />
</div>
```

### SCSS

```scss
.tooltip-container {
    position: relative;
    display: inline-block;

    .custom-tooltip {
        cursor: pointer;

        .tooltip-text {
            visibility: hidden;
            opacity: 0;
            transition: opacity 0.2s ease-in-out;
            position: absolute;
            bottom: 100%; // Измените эту строку для настройки положения
            left: 50%;
            transform: translateX(-50%);
            background-color: #333;
            color: #fff;
            padding: 5px;
            border-radius: 4px;
            z-index: 10;

            &.show {
                visibility: visible;
                opacity: 1;
            }
        }
    }
}
```

### JavaScript (jQuery)

```javascript
$(document).ready(function () {
    $('.custom-tooltip').mouseenter(function () {
        const $tooltipText = $('<div class="tooltip-text"></div>').text($(this).data('tooltip'));
        $(this).append($tooltipText);
        
        const rect = $tooltipText[0].getBoundingClientRect();
        const viewportHeight = $(window).height();

        if (rect.top < 0 || rect.bottom > viewportHeight) {
            $tooltipText.css({ bottom: '100%' }); // Можно поменять на выше
        } else {
            $tooltipText.css({ top: '100%' }); // Отображение ниже элемента
        }

        $tooltipText.addClass('show');
    }).mouseleave(function () {
        $(this).find('.tooltip-text').remove();
    });
});
```

### Интеграция с Thymeleaf

Предположим, что у вас есть объект, который отображается в вашем шаблоне Thymeleaf, и вы хотите использовать tooltip для него. Например, вы можете вывести текст из модели следующим образом:

```html
<div class="tooltip-container">
    <span class="custom-tooltip" data-tooltip="${tooltipText}">Наведи на меня</span>
    <input type="text" placeholder="Поле ввода" />
</div>
```

### Пояснение

1. **HTML**: Мы создаём элемент с классом `custom-tooltip` и добавляем `data-tooltip` атрибут, который будет содержать текст подсказки.
  
2. **SCSS**: Мы создаём стиль для tooltip, который будет скрыт по умолчанию. Когда добавляется класс `show`, он становится видимым.

3. **JavaScript**: При наведении на элемент с классом `custom-tooltip`, создаётся новый элемент `div` для текста подсказки, который будет добавлен в DOM. Мы также проверяем, вмещается ли tooltip в окно просмотра экрана, и изменяем его положение, если это необходимо.

4. **Thymeleaf**: Вы можете динамически передавать текст подсказки из вашей модели, используя выражение `${tooltipText}`.

Этот код реализует простой и понятный tooltip, который может быть легко настроен по вашим требованиям.
А зачем такие сложности с такой простой задачей, как тултипы? Их ведь можно реализовать полностью на CSS, просто добавив нужному элементу, например, атрибут "tooltip" 


Анимацию уже сами добавите, если очень нужна

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


.custom-tooltip:has(+ *:hover) означает, что выбрать надо те элементы .custom-tooltip, у которых на следующем за ними элементе наведена мышь.
"+" выбор непосредственно следующего элемента
"+ *" - выбор любого непосредственного следующего элемента
"+ *:hover" - выбор любого непосредственного следующего элемента, на который наведена мышь.
has выбирает элементы .custom-tooltip, с которым связаны элементы, выбранные при помощи уточняющего селектора в скобках.
Похожие вопросы