SmthTo
@SmthTo
Все перепёлки мира будут оплакивать мою смерть.

Как сделать автоматический рассчет высоты каждого элемента группы на JS?

Товарищи, здравствуйте!

Я страдал фигней и сделал аж целое интерактивное эссе, в чем заключается моя задача:


В песочнице выше -- я описал все, что нужно, но продублирую сюда. Сразу скажу, что я в JavaScript -- словно заяц в космосе, т. е. мёртвый абсолютно. Вопрос такой: нужно сделать тень под блоком, как на divan.ру (к примеру, тут). Когда наводишь на карточку товара, под ней появляется блок с тенью, а также блок к кнопкой и дополнительной информацией. Оба блока на абсолютном позиционировании. Блок с информацией кнопкой может иметь разную высоту, что сразу отметает возможность задавать жесткий размер тени с учетом высоты этого блока. Там используется JS по причине невозможности сделать данный расчет на CSS.

В песочнице есть убогий неработающий скрипт-попытка на JQuery, но это даже стыдно обсуждать.

Подскажите пожалуйста, в каком направлении двигать в данном случае, может, есть примеры, спасибо!

P. S. Наверное, я неверно описал задачу -- просто я косой, извините.
  • Вопрос задан
  • 427 просмотров
Решения вопроса 2
space2pacman
@space2pacman
Просто царь.
https://jsfiddle.net/j0hzu8nx/15/
var shadow = $(this).find('.shadow');
var button = $(this).find('.button');

shadow.height(shadow.height() + button.height() + 20)
Ответ написан
Комментировать
SmthTo
@SmthTo Автор вопроса
Все перепёлки мира будут оплакивать мою смерть.
Комбинируя ответ Ярослав Иванов, идею касательно hover'а от Арсений Матыцин и делегирование функций, на нативном JS можно сделать так:
// наведение
document.body.addEventListener("mouseenter", function(e) {
  if (e.target.classList.contains('item')) {
 
    let item = e.target;
    let itemShadowGap = 15;
    let itemShadow = item.querySelectorAll('.shadow')[0];
    let itemBottom = item.querySelectorAll('.button')[0];
    let itemShadowHeight = itemShadow.scrollHeight + itemBottom.scrollHeight + itemShadowGap;

    // проверяем, нет ли атрибута
    if (!item.hasAttribute('data-shadow-limiter-delay')) {
      item.setAttribute('data-shadow-limiter-delay', true);
      itemShadow.style.maxHeight = '' + itemShadowHeight + 'px';
    }

    item.style.zIndex = '10';
    itemShadow.style.height = '' + itemShadowHeight + 'px';

  }
}, true);

// отведение
document.body.addEventListener("mouseleave", function(e) {
  if (e.target.classList.contains('item')) {
  
    let item = e.target;
    let itemShadow = item.querySelectorAll('.shadow')[0];
    let itemShadowHeight = itemShadow.scrollHeight;

    // убираем максимальную высоту и атрубут по задержке
    if (item.hasAttribute('data-shadow-limiter-delay')) {
      setTimeout(function() {
        item.removeAttribute('data-shadow-limiter-delay');
        itemShadow.style.maxHeight = '';
      }, 3000);
    }

    item.style.zIndex = '';
    itemShadow.style.height = '';

  }
}, true);


Таким образом решается вопрос с адаптивностью (высота считается при каждом hover'e), а также функция работает с динамически созданными элементами. Проверил на старом ноутбуке (мобильный Core i5 2-го поколения, 4 Гб ОЗУ и встроенная видеокарта; FireFox, Chrome, IE11), нет никаких задержек обработки скрипта в условии наличия 600 ед. элементов. И это с учетом всех остальных скриптов на сайте.

Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
ArsenyMatytsyn
@ArsenyMatytsyn Куратор тега JavaScript
Руководитель frontend направления, предприниматель
Подход к вопросу огонь. Но. Как по мне, тут js не шибко и нужен. +- хватит танцев с бубном на css, путем осознания того, что в общем информация статична, и высчитывать шибко и нечего. Ну и немного абсолютного позиционирования и хаков.
Но если действительно стоит необходимость сделать, так сказать, умную сетку, то можно перебирать их всех после полной загрузки DOM, или же еще лучше, индивидуально в момент hover. К слову, jQuery можно... В общем чистый JS нынче в треде, как говорится. Итак, ближе к конкретике:
  1. Спаси и сохрани размер обертки карточки, назовем ее ячейкой
  2. Задай самой карточке абсолютное позиционирование относительно ячейки
  3. Задисплей через прозрачность (к примеру) дополнительные элементы
  4. Рассчитай их размеры и, как в примере на дверях, высчитай отступ наверх

Ну и главное, проверь, чтобы у ячейки не стял overflow:hidden. Бо плохо будет.
З.Ы.: кроме морды из примера я ничего не увидел. Ну и пункты могут варьироваться.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы