Как в 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" <br/> <br/> <br/> Анимацию уже сами добавите, если очень нужна <br/> <br/> Если же очень хотите именно при наведении на следующий элемент что-то делать, то могу просто предложить идею селектора, который позволяет таким образом выбирать <br/> <br/> <br/> <b>.custom-tooltip:has(+ *:hover)</b> означает, что выбрать надо те элементы .custom-tooltip, у которых на следующем за ними элементе наведена мышь. <br/> <b>"+"</b> выбор непосредственно следующего элемента <br/> <b>"+ *"</b> - выбор любого непосредственного следующего элемента <br/> <b>"+ *:hover" </b> - выбор любого непосредственного следующего элемента, на который наведена мышь. <br/> <b>has</b> выбирает элементы .custom-tooltip, с которым связаны элементы, выбранные при помощи уточняющего селектора в скобках.
Похожие вопросы