Подтвердить что ты не робот

Нужно найти высоту скрытого div на странице (установлен для отображения: нет)

Мне нужно измерить offsetHeight div, который находится внутри скрытого элемента.

<div id="parent" style="display: none;">
    <div id="child">Lorem Ipsum dolor sit amet.</div>
</div>

Родительский div должен быть установлен на "display:none". Я не контролирую это. Я понимаю, что offsetHeight дочернего div будет 0. Мне нужно найти обходное решение.

Что-то, с чем я играл, - это когда загружается страница, я копирую дочерние элементы родителя, вставляю в div на странице, которая установлена ​​на "visiblity:hidden". Затем я измеряю высоту этих элементов и удаляю узлы по завершении.

Любые другие мысли?

Update: Что мне пришлось сделать, так это:

Используя YUI 2, на загрузке страницы, я нашел все элементы этого заданного имени класса, которые либо были установлены для отображения: none, либо высота и ширина которых равны 0 (один способ измерения существования элемента или родителя для отображения: нет). Затем я устанавливаю этот элемент для отображения: block. Затем я проверил его родитель для того же самого и показал родителям, пока не найдет видимого родителя. После наивысшего отображения: ни один предк не установлен для отображения: block, я могу измерить свой элемент.

После измерения всех элементов я reset все элементы, возвращаемые на дисплей: none.

4b9b3361

Ответ 1

Вам нужно сделать элемент parent visible видимым за этот очень короткий момент, пока вы получаете размеры элемента. В общем решении все предки обычно пересекаются и становятся видимыми. Затем их значения display возвращаются к исходным.

Конечно, проблемы с производительностью.

Мы рассмотрели этот подход в реализации Prototype.js, но закончили с getWidth и getHeight , делая только действительный элемент видимым, не пересекая предков.

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

<div class="foo" style="display:none;">
  <div class="bar">...</div>
</div>

и эти правила:

.bar { width: 10em; }
.foo .bar { width: 15em; }

то извлечение элемента из его родителя приведет к неправильным измерениям.

Ответ 2

Вы можете клонировать элемент, полностью позиционировать его на -10000, -10000, измерять клон и уничтожать его.

Ответ 3

Если вы используете style.display = "none", элемент будет иметь ширину и высоту,
но используя style.visibility = "hidden" вместо этого, элемент будет иметь ширину и высоту, вычисленные браузером (как обычно).

Ответ 4

Сделано чистым js-решением без JQuery и без клонирования (что, я думаю, быстрее)

var getHeight = function(el) {
    var el_style      = window.getComputedStyle(el),
        el_display    = el_style.display,
        el_position   = el_style.position,
        el_visibility = el_style.visibility,
        el_max_height = el_style.maxHeight.replace('px', '').replace('%', ''),

        wanted_height = 0;

    // if its not hidden we just return normal height
    if(el_display !== 'none' && el_max_height !== '0') {
        return el.offsetHeight;
    }

    // the element is hidden so:
    // making the el block so we can meassure its height but still be hidden
    el.style.position   = 'absolute';
    el.style.visibility = 'hidden';
    el.style.display    = 'block';

    wanted_height     = el.offsetHeight;

    // reverting to the original values
    el.style.display    = el_display;
    el.style.position   = el_position;
    el.style.visibility = el_visibility;

    return wanted_height;
}

вот демонстрация https://jsfiddle.net/xuumzf9k/1/

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

Ответ 5

Итак, здесь работает решение jQuery на основе ответа lod3n и с помощью комментария 999:

var getHiddenElementHeight = function(element){
    var tempId = 'tmp-'+Math.floor(Math.random()*99999);//generating unique id just in case
    $(element).clone()
    .css('position','absolute')
    .css('height','auto').css('width','1000px')
    //inject right into parent element so all the css applies (yes, i know, except the :first-child and other pseudo stuff..
    .appendTo($(element).parent())
    .css('left','-10000em')
    .addClass(tempId).show()
    h = $('.'+tempId).height()
    $('.'+tempId).remove()
    return h;
}

Наслаждайтесь!

Ответ 6

Используйте z-index, чтобы скрыть элемент под непрозрачным элементом, показать его и получить высоту.

Ответ 7

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

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

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

Ответ 8

Итак, вы даже не можете изменить display:none; на height:0; overflow:hidden;? Возможно, вы можете переопределить это в своей собственной таблице стилей так:

div#parent { display: block !important; height:0; overflow:hidden; }

И тогда, когда вы используете YUI (предполагая YUI 2), вы можете использовать это:

var region = YAHOO.util.Dom.getRegion('child');

Чтобы получить размеры и смещение дочернего элемента.

Ответ 9

Попробуйте использовать:

#parent{ display:block !important; visibility:hidden; position:absolute} 

Ответ 10

Обходной путь должен установить height 0

.hidden { 
  height:0; 
  overflow: hidden; 
}

Затем получить элементы scrollHeight.

document.querySelector('.hidden').scrollHeight

ScrollHeight правильно даст вам высоту, хотя элемент не появляется. Я не думаю, что это также влияет на поток элементов.

Пример: https://jsfiddle.net/de3vk8p4/7/

Ответ 11

Что мне пришлось сделать, так это:

Используя YUI 2, на загрузке страницы, я нашел все элементы этого заданного имени класса, которые либо были установлены для отображения: none, либо высота и ширина которых равны 0 (один способ измерения существования элемента или родителя для отображения: нет). Затем я устанавливаю этот элемент для отображения: block. Затем я проверил его родитель для того же самого и показал родителям, пока не найдет видимого родителя. После наивысшего отображения: ни один предк не установлен для отображения: block, я могу измерить свой элемент.

После измерения всех элементов я reset все элементы, возвращаемые на дисплей: none.

Ответ 12

Вспомогательная функция ---

function getElementHeight(el) {
  var clone           = el.cloneNode(true);
  var width           = el.getBoundingClientRect().width;
  clone.style.cssText = 'position: fixed; top: 0; left: 0; overflow: auto; visibility: hidden; pointer-events: none; height: unset; max-height: unset; width: ' + width + 'px';
  document.body.append(clone);
  var height = clone.getBoundingClientRect().height + 'px';
  clone.remove();
  return height;
}

Создает клон, добавляет его в DOM (скрытый), получает высоту, а затем удаляет его.

Положение fixed и top/left в случае, если ваше приложение позволяет прокручивать на уровне тела - оно пытается предотвратить вечеринку полосы прокрутки - может удалить, если вы обрабатываете прокрутку в дочерних элементах.

Настройки Overflow, height и max-height, чтобы попытаться "сбросить" настройки высоты и сделать ее естественной высотой для клона.

Visibility для явных и указательных событий как "на всякий случай", рендеринг элемента занимает некоторое время и не хочет прерывать пользовательский ввод.

Пример с анимированным аккордеонным открытием/закрытием, учитывающим динамические высоты.

function getElementHeight(el) {
  var clone = el.cloneNode(true);
  clone.style.cssText = 'position: fixed; top: 0; left: 0; overflow: auto; visibility: hidden; pointer-events: none; height: unset; max-height: unset';
  document.body.append(clone);
  var height = clone.getBoundingClientRect().height + 'px';
  clone.remove();
  return height;
}

var expanded = false;

function toggle() {
  var el = document.getElementById('example');
  expanded = !expanded;

  if (expanded) {
    el.style.maxHeight = getElementHeight(el);

    // Remove max-height setting to allow dynamic height after it shown
    setTimeout(function() {
      el.style.maxHeight = 'unset';
    }, 1000); // Match transition
  } else {
    // Set max height to current height for something to animate from
    el.style.maxHeight = getElementHeight(el);

    // Let DOM element update max-height, then set to 0 for animated close
    setTimeout(function() {
      el.style.maxHeight = 0;
    }, 1);
  }
}
#example {
  overflow: hidden;
  max-height: 0;
  transition: max-height 1s;
}
<button onclick="toggle()">Toggle</button>
<div id="example">
  <textarea>Resize me</textarea>
</div>

Ответ 13

Вы пробовали это?

setTimeout('alert($(".Var").height());',200);