jQuery: получить высоту скрытого элемента в jQuery. - PullRequest
242 голосов
/ 27 февраля 2010

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

Я использую jQuery 1.4.2:

$select.show();
optionHeight = $firstOption.height(); //we can only get height if its visible
$select.hide();

Ответы [ 14 ]

176 голосов
/ 27 февраля 2010

Вы могли бы сделать что-то вроде этого, хотя и немного глупо, забудьте position, если оно уже абсолютное:

var previousCss  = $("#myDiv").attr("style");

$("#myDiv").css({
    position:   'absolute', // Optional if #myDiv is already absolute
    visibility: 'hidden',
    display:    'block'
});

optionHeight = $("#myDiv").height();

$("#myDiv").attr("style", previousCss ? previousCss : "");
91 голосов
/ 05 апреля 2011

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

$('#some-element').height();

использовать

$('#some-element').actual('height');

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

Полную документацию смотрите здесь . На странице также есть демо-версия.

Надеюсь, эта помощь:)

38 голосов
/ 27 февраля 2010

Вы используете два стиля CSS: стиль отображения и стиль отображения .

Если элемент скрыт путем установки стиля css видимости, тогда вы сможете получить высоту независимо от того, видим элемент или нет, так как элемент все еще занимает место на странице .

Если элемент скрыт путем изменения стиля отображения css на «none», тогда элемент не занимает места на странице, и вам придется придать ему стиль отображения, который заставит элемент визуализироваться в некоторых пространство, в котором вы можете получить высоту.

29 голосов
/ 31 марта 2010

Я действительно прибегал к хитрости, чтобы справиться с этим время от времени. Я разработал виджет полосы прокрутки jQuery, где столкнулся с проблемой, которую я не знаю заранее, является ли прокручиваемый контент частью скрытой части разметки или нет. Вот что я сделал:

// try to grab the height of the elem
if (this.element.height() > 0) {
    var scroller_height = this.element.height();
    var scroller_width = this.element.width();

// if height is zero, then we're dealing with a hidden element
} else {
    var copied_elem = this.element.clone()
                      .attr("id", false)
                      .css({visibility:"hidden", display:"block", 
                               position:"absolute"});
    $("body").append(copied_elem);
    var scroller_height = copied_elem.height();
    var scroller_width = copied_elem.width();
    copied_elem.remove();
}

По большей части это работает, но есть потенциальная проблема, которая может возникнуть. Если контент, который вы клонируете, стилизован с помощью CSS, который включает в свои правила ссылки на родительскую разметку, клонированный контент не будет содержать соответствующий стиль и, вероятно, будет иметь несколько иные измерения. Чтобы обойти это, вы можете убедиться, что к разметке, которую вы клонируете, применяются правила CSS, которые не включают ссылки на родительскую разметку.

Кроме того, это не подошло для меня с моим виджетом скроллера, но чтобы получить соответствующую высоту клонированного элемента, вам нужно установить ширину равной ширине родительского элемента. В моем случае CSS-ширина всегда применялась к реальному элементу, поэтому мне не пришлось об этом беспокоиться, однако, если к элементу не применена ширина, вам может потребоваться выполнить некоторую рекурсивную процедуру. Обход DOM-элемента элемента для определения ширины соответствующего родительского элемента.

12 голосов
/ 12 января 2012

Основываясь на ответе пользователя Ника и плагине hitautodestruct пользователя на JSBin, я создал аналогичный плагин jQuery, который получает ширину и высоту и возвращает объект, содержащий эти значения.

Его можно найти здесь: http://jsbin.com/ikogez/3/

Обновление

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

Это работает отлично:

/**
 * getSize plugin
 * This plugin can be used to get the width and height from hidden elements in the DOM.
 * It can be used on a jQuery element and will retun an object containing the width
 * and height of that element.
 *
 * Discussed at StackOverflow:
 * http://stackoverflow.com/a/8839261/1146033
 *
 * @author Robin van Baalen <robin@neverwoods.com>
 * @version 1.1
 * 
 * CHANGELOG
 *  1.0 - Initial release
 *  1.1 - Completely revamped internal logic to be compatible with javascript-intense environments
 *
 * @return {object} The returned object is a native javascript object
 *                  (not jQuery, and therefore not chainable!!) that
 *                  contains the width and height of the given element.
 */
$.fn.getSize = function() {    
    var $wrap = $("<div />").appendTo($("body"));
    $wrap.css({
        "position":   "absolute !important",
        "visibility": "hidden !important",
        "display":    "block !important"
    });

    $clone = $(this).clone().appendTo($wrap);

    sizes = {
        "width": $clone.width(),
        "height": $clone.height()
    };

    $wrap.remove();

    return sizes;
};
12 голосов
/ 13 апреля 2011

Опираясь на ответ Ника:

$("#myDiv").css({'position':'absolute','visibility':'hidden', 'display':'block'});
optionHeight = $("#myDiv").height();
$("#myDiv").css({'position':'static','visibility':'visible', 'display':'none'});

Я обнаружил, что лучше сделать это:

$("#myDiv").css({'position':'absolute','visibility':'hidden', 'display':'block'});
optionHeight = $("#myDiv").height();
$("#myDiv").removeAttr('style');

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

4 голосов
/ 16 июня 2010

Вы также можете расположить скрытый div с экрана с отрицательным полем, а не с помощью display: none, очень похоже на технику замены изображения с отступом текста.

например.

position:absolute;
left:  -2000px;
top: 0;

Таким образом, высота () все еще доступна.

2 голосов
/ 20 октября 2013

Я пытаюсь найти работающую функцию для скрытого элемента, но я понимаю, что CSS намного сложнее, чем все думают. В CSS3 есть много новых методов верстки, которые могут не работать для всех предыдущих ответов, таких как гибкое поле, сетка, столбец или даже элемент внутри сложного родительского элемента.

Пример flexibox enter image description here

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

К сожалению, JavaScript не предоставляет какого-либо прямого события, чтобы уведомить, когда элемент показан или скрыт. Тем не менее, я создаю некоторую функцию на основе DOM Attribute Modified API, которая будет выполнять функцию обратного вызова при изменении видимости элемента.

$('[selector]').onVisibleChanged(function(e, isVisible)
{
    var realWidth = $('[selector]').width();
    var realHeight = $('[selector]').height();

    // render or adjust something
});

Для получения дополнительной информации, пожалуйста, посетите в моем проекте GitHub.

https://github.com/Soul-Master/visible.event.js

демо: http://jsbin.com/ETiGIre/7

2 голосов
/ 23 сентября 2013

Следуя решению Ника Крейвера, настройка видимости элемента позволяет ему получать точные размеры. Я использовал это решение очень очень часто. Однако, чтобы сбросить стили вручную, я пришел к выводу, что это громоздко, учитывая, что, изменяя первоначальное позиционирование / отображение элемента в моем css в процессе разработки, я часто забываю обновить соответствующий код javascript. Следующий код не сбрасывает стили, скажем так, но удаляет встроенные стили, добавленные javascript:

$("#myDiv")
.css({
    position:   'absolute',
    visibility: 'hidden',
    display:    'block'
});

optionHeight = $("#myDiv").height();
optionWidth = $("#myDiv").width();

$("#myDiv").attr('style', '');

Единственное допущение здесь состоит в том, что не может быть других встроенных стилей, иначе они также будут удалены. Преимущество здесь заключается в том, что стили элемента возвращаются к тому, что было в таблице стилей CSS. Как следствие, вы можете записать это как функцию, через которую передается элемент и возвращается высота или ширина.

Другая проблема, с которой я столкнулся при установке встроенных стилей с помощью js, заключается в том, что при работе с переходами через css3 вы вынуждены адаптировать веса ваших правил стиля, чтобы они были сильнее встроенного стиля, что иногда может расстраивать. 1006 *

1 голос
/ 09 мая 2015

Один из обходных путей - создать родительский div вне элемента, для которого вы хотите получить высоту, применить высоту «0» и скрыть любое переполнение. Затем возьмите высоту дочернего элемента и удалите свойство overflow родительского элемента.

var height = $("#child").height();
// Do something here
$("#parent").append(height).removeClass("overflow-y-hidden");
.overflow-y-hidden {
  height: 0px;
  overflow-y: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="parent" class="overflow-y-hidden">
  <div id="child">
    This is some content I would like to get the height of!
  </div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...