jQuery : jQuery에서 숨겨진 요소의 높이 가져 오기


249

숨겨진 div 내에있는 요소의 높이를 가져와야합니다. 지금은 div를 보여주고 높이를 얻고 부모 div를 숨 깁니다. 이것은 약간 어리석은 것 같습니다. 더 좋은 방법이 있습니까?

jQuery 1.4.2를 사용하고 있습니다.

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

42
+1 예제 솔루션이 실제로 어떤 롤보다 우수합니다.
Tim Santeford

9
팀에 동의하지 않습니다. 이 솔루션을 사용하면 실제로 항목을 표시 한 다음 숨기므로 화면이 깜박일 수 있습니다. Nicks 솔루션이 더 복잡 해지더라도 상위 div가 표시되지 않으므로 디스플레이가 깜박일 가능성이 없습니다.
Humphrey



5
Harry, 실제로 당신이 알게 된 것은 코드 가이 솔루션이 아니라 IE에서 작동하지 않는다는 것입니다. 코드를 디버그 해보세요 :)
Gavin

답변:


181

조금 해 키지 만 다음과 같이 할 수 있습니다 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 : "");

17
위의 코드를 jQ 플러그인 jsbin.com/ihakid/2에 통합했습니다 . 또한 클래스를 사용하고 부모도 숨겨져 있는지 확인합니다.
hitautodestruct

3
+1 훌륭합니다. 요소의 부모도 표시되어야 함을 명심하십시오. 이것은 몇 분 동안 혼란 스러웠습니다. 또한 요소가 인 경우 position:relative물론 대신 요소 를 설정하려고합니다 static.
Michael Mior

6
이 방법을 사용하면 대상 요소의 모양이 변경 될 수 있습니다. 따라서 div가 절대 위치에있을 때 높이 및 / 또는 너비를 얻는 것은별로 유용하지 않을 수 있습니다.
Jeremy Ricketts

2
@Gavin 이것은 리플로 계산과 사용자에게 깜박임을 방지하므로 저렴하고 덜 관입 적입니다.
Nick Craver

2
@hitautodestruct, 요소가 실제로 숨겨져 있는지 확인하기 위해 쿼리 플러그인을 수정했습니다. jsbin.com/ihakid/58
Prasad

96

숨겨진 요소 너비를 얻는 것과 동일한 문제가 발생했기 때문에이 플러그인 호출 jQuery Actual 을 작성하여 문제를 해결했습니다. 사용하는 대신

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

사용하다

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

숨겨진 요소에 대한 올바른 값을 제공하거나 요소에 숨겨진 부모가 있습니다.

전체 문서는 여기 를 참조 하십시오 . 페이지에 데모 포함도 있습니다.

이 도움을 바랍니다 :)


3
그렇습니다. 2015 년에도 여전히 도움이됩니다. 실제 웹 사이트에서 "이전 버전의 jquery"라고 말하지만 v2.1.3에서는 여전히 필요합니다. 적어도 제 상황에서는 그렇습니다.
LpLrich

감사! 나는 아코디언 내에서 처음에 숨겨진 요소의 높이를 (이 동적으로 이루어집니다) 읽기 및 설정이 플러그인을 사용
ALDS

멋진 플러그인! 100 %로 설정했을 때 모달 내부의 div 너비를 얻기 위해 모든 것을 시도했지만 아무것도 작동하지 않았습니다. 이것을 5 초 안에 설정하고 완벽하게 작동했습니다!
Craig Howell

@ben 링크가 끊어졌습니다.
Sachin Prasad

39

두 가지 CSS 스타일 인 표시 스타일가시성 스타일을 혼동 하고 있습니다 .

가시성 CSS 스타일을 설정하여 요소를 숨기면 요소가 페이지에서 공간을 차지하는 지에 따라 요소의 표시 여부에 관계없이 높이를 얻을 수 있습니다 .

표시 CSS 스타일을 "없음"으로 변경하여 요소를 숨기면 요소가 페이지에서 공간을 차지하지 않으므로 요소가 일부 공간에서 렌더링되도록하는 표시 스타일을 지정해야합니다. 어느 지점에서 높이를 얻을 수 있습니다.


이것에 감사합니다. 내 문제는 테이블 셀을 포함하고 설정 visibility하는 hidden내 문제가 해결되지 않았지만, 그것은 세트 나에게 아이디어를 준 position: fixed; top: 100%하고 그것이 마치 마법처럼 작동합니다!
Jayen

이제 높이가 display : none 요소와 함께 표시되지 않는 이유를 이해합니다. 훌륭한 설명을 주셔서 감사합니다.
FrenkyB

30

나는 실제로 이것을 다루기 위해 약간의 속임수에 의지했습니다. 스크롤 가능한 콘텐츠가 숨겨진 마크 업의 일부인지 여부를 미리 알 수없는 문제가 발생하는 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 조상의 순회.


그래도 흥미로운 문제가 있습니다. 요소가 이미 블록 요소 인 경우 복제본은 전체 바디 너비 (바디 패딩 또는 여백 제외)를 가져옵니다. 컨테이너 내부의 크기와 다릅니다.
Meligy 2012

16

사용자 Nick의 답변과 JSBin에서 사용자 hitautodestruct의 플러그인을 더 발전 시켜서 너비와 높이를 모두 검색하고 이러한 값을 포함하는 객체를 반환하는 비슷한 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;
};

코드가 올바르지 않습니다. 보이지 않는 원래 항목을 참조 해야 sizes = {"width": $wrap.width(), "height": $wrap.height()};합니다 this.
jackJoe

@ jackJoe 나는이 코드를 꽤 오랫동안 문제없이 사용하고 있습니다. 기껏해야 'this'대신 $ clone.width ()가 필요하다고 말할 것입니다. 랩 내부의 요소 크기를 원하므로 $ wrap이 아닙니다. 래퍼는 10000x10000px 일 수 있지만 측정하려는 요소는 여전히 30x40px입니다.
Robin van Baalen

를 타겟팅해도 $wrap괜찮습니다 (적어도 내 테스트에서는). 나는로 시도했지만 this분명히 this숨겨진 요소를 참조하기 때문에 크기를 잡지 못합니다 .
jackJoe

1
감사합니다 @jackJoe 이제 코드 예제를 업데이트했습니다.
Robin van Baalen

12

Nick의 답변을 더 발전시키는 것 :

$("#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 파일에있는 다른 속성을 덮어 씁니다. HTML 요소에서 스타일 속성을 제거하면 모든 것이 정상으로 돌아가고 처음에는 숨겨져 있기 때문에 여전히 숨겨져 있습니다.


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

9
... 요소에 이미 인라인 스타일이없는 한. jQuery로 요소를 숨기면 어떤 경우가 될 것입니다.
Muhd

4

텍스트 들여 쓰기 이미지 대체 기술과 같이 display : none을 사용하지 않고 음수 여백으로 화면 밖으로 숨겨진 div를 배치 할 수도 있습니다.

예.

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

이 방법으로 height ()를 계속 사용할 수 있습니다.


3

숨겨진 요소에 대한 작업 기능을 찾으려고하지만 CSS는 모든 사람이 생각하는 것보다 훨씬 복잡하다는 것을 알고 있습니다. CSS3에는 유연한 상자, 격자, 열 또는 복잡한 부모 요소 내부의 요소와 같은 이전의 모든 답변에서 작동하지 않을 수있는 새로운 레이아웃 기술이 많이 있습니다.

flexibox 예 여기에 이미지 설명을 입력하십시오

지속 가능하고 간단한 유일한 솔루션은 실시간 렌더링 이라고 생각합니다 . 이때 브라우저는 올바른 요소 크기를 제공해야합니다 .

안타깝게도 JavaScript는 요소가 표시되거나 숨겨 질 때 알려주는 직접적인 이벤트를 제공하지 않습니다. 그러나 요소의 가시성이 변경되면 콜백 함수를 실행하는 DOM 속성 수정 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


답변 주셔서 감사합니다. MutationObservers를 사용하도록 영감을 받았습니다. 그러나 라이브러리는 style속성 변경으로 인한 가시성 변경 만 확인하고 ( 여기 59 행 참조) 속성 변경 으로 인해 가시성 변경이 발생할 수 있습니다 class.
Ashraf Sabry

네가 옳아. 올바른 문장은 e.attributeName! == 'style'&& e.attributeName! == 'className'이어야합니다.
Soul_Master

2

Nick Craver의 솔루션에 따라 요소의 가시성을 설정하면 정확한 치수를 얻을 수 있습니다. 이 솔루션을 매우 자주 사용했습니다. 그러나 스타일을 수동으로 재설정 해야하는 경우 개발을 통해 CSS에서 요소의 초기 위치 지정 / 표시를 수정하면 관련 자바 스크립트 코드를 업데이트하는 것을 종종 잊어 버립니다. 다음 코드는 말 당 스타일을 재설정하지 않지만 자바 스크립트로 추가 된 인라인 스타일을 제거합니다.

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

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

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

여기서 유일한 가정은 다른 인라인 스타일이 없거나 다른 스타일도 제거된다는 것입니다. 그러나 여기서 이점은 요소의 스타일이 CSS 스타일 시트에 있던 스타일로 반환된다는 것입니다. 결과적으로 이것을 요소가 전달되고 높이 또는 너비가 반환되는 함수로 작성할 수 있습니다.

js를 통해 스타일을 인라인으로 설정하는 또 다른 문제는 css3를 통한 전환을 처리 할 때 스타일 규칙의 가중치를 인라인 스타일보다 더 강하게 적용해야하므로 때로는 실망 스러울 수 있다는 것입니다.


1

정의에 따르면 요소는 보이는 경우에만 높이를 갖습니다.

궁금한 점 : 숨겨진 요소의 높이가 왜 필요한가요?

한 가지 대안은 z- 인덱스를 사용하여 오버레이를 배치하여 요소 를 효과적으로 숨기는 것입니다.


1
높이를 원할 때 숨겨지는 요소의 높이가 필요합니다. 내가 플러그인을 구축하고 있고 나는 그것을 init로 일부 데이터를 수집 할 필요가
mkoryak

2
또 다른 이유는 아직 보이지 않을 수있는 자바 스크립트로 물건을 중앙에 배치하는 것입니다.
Simon_Weaver

@cletus 만약 당신이 단지 주석을 작성하는 것을 원한다면, 그것은 종종 숨겨진 요소의 크기를 얻기 위해 프론트 엔드 코딩에서 상황입니다.
Rantiev

1

내 상황에서 나는 또한 높이 값을 얻는 것을 막는 숨겨진 요소가 있었지만 요소 자체가 아니라 부모 중 하나였습니다 ... 그래서 플러그인 중 하나가 있는지 확인하기 만하면됩니다. 숨겨진 경우 가장 가까운 숨겨진 요소를 찾으십시오. 예를 들면 다음과 같습니다.

var $content = $('.content'),
    contentHeight = $content.height(),
    contentWidth = $content.width(),
    $closestHidden,
    styleAttrValue,
    limit = 20; //failsafe

if (!contentHeight) {
    $closestHidden = $content;
    //if the main element itself isn't hidden then roll through the parents
    if ($closestHidden.css('display') !== 'none') { 
        while ($closestHidden.css('display') !== 'none' && $closestHidden.size() && limit) {
            $closestHidden = $closestHidden.parent().closest(':hidden');
            limit--;
        }
    }
    styleAttrValue = $closestHidden.attr('style');
    $closestHidden.css({
        position:   'absolute',
        visibility: 'hidden',
        display:    'block'
    });
    contentHeight = $content.height();
    contentWidth = $content.width();

    if (styleAttrValue) {
        $closestHidden.attr('style',styleAttrValue);
    } else {
        $closestHidden.removeAttr('style');
    }
}

실제로 이것은 Nick, Gregory 및 Eyelidlessness의 응답을 결합하여 Gregory의 개선 된 방법을 사용하지만 스타일 속성에 무언가 되돌려 놓을 것으로 예상되는 경우 두 방법을 모두 사용합니다. 부모 요소.

내 솔루션에 대한 유일한 단점은 부모를 통한 루프가 완전히 효율적이지 않다는 것입니다.


1

한 가지 해결 방법은 높이를 얻으려는 요소 외부에 부모 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>


0

다음은 숨겨진 요소, 숨겨진 부모의 자손에 대한 모든 jQuery의 차원 메소드를 처리하기 위해 작성한 스크립트입니다. 물론 이것을 사용하면 성능이 저하됩니다.

// Correctly calculate dimensions of hidden elements
(function($) {
    var originals = {},
        keys = [
            'width',
            'height',
            'innerWidth',
            'innerHeight',
            'outerWidth',
            'outerHeight',
            'offset',
            'scrollTop',
            'scrollLeft'
        ],
        isVisible = function(el) {
            el = $(el);
            el.data('hidden', []);

            var visible = true,
                parents = el.parents(),
                hiddenData = el.data('hidden');

            if(!el.is(':visible')) {
                visible = false;
                hiddenData[hiddenData.length] = el;
            }

            parents.each(function(i, parent) {
                parent = $(parent);
                if(!parent.is(':visible')) {
                    visible = false;
                    hiddenData[hiddenData.length] = parent;
                }
            });
            return visible;
        };

    $.each(keys, function(i, dimension) {
        originals[dimension] = $.fn[dimension];

        $.fn[dimension] = function(size) {
            var el = $(this[0]);

            if(
                (
                    size !== undefined &&
                    !(
                        (dimension == 'outerHeight' || 
                            dimension == 'outerWidth') &&
                        (size === true || size === false)
                    )
                ) ||
                isVisible(el)
            ) {
                return originals[dimension].call(this, size);
            }

            var hiddenData = el.data('hidden'),
                topHidden = hiddenData[hiddenData.length - 1],
                topHiddenClone = topHidden.clone(true),
                topHiddenDescendants = topHidden.find('*').andSelf(),
                topHiddenCloneDescendants = topHiddenClone.find('*').andSelf(),
                elIndex = topHiddenDescendants.index(el[0]),
                clone = topHiddenCloneDescendants[elIndex],
                ret;

            $.each(hiddenData, function(i, hidden) {
                var index = topHiddenDescendants.index(hidden);
                $(topHiddenCloneDescendants[index]).show();
            });
            topHidden.before(topHiddenClone);

            if(dimension == 'outerHeight' || dimension == 'outerWidth') {
                ret = $(clone)[dimension](size ? true : false);
            } else {
                ret = $(clone)[dimension]();
            }

            topHiddenClone.remove();
            return ret;
        };
    });
})(jQuery);

눈꺼풀이없는 대답은 내가 필요한 것에 완벽하게 보이지만 실행중인 jQuery와 작동하지 않습니다. 1.3.2 jQuery가 this.clone (또는 매우 가까운 무언가)을 던지게하는 것은 함수가 아닙니다. 누구나 고치는 방법에 대한 아이디어가 있습니까?

0

이전에 페이지에 요소를 이미 표시 한 경우 요소가 숨겨져 있어도 설정되므로 DOM 요소 (.get (0)을 사용하여 jQuery에서 도달 가능)에서 직접 높이를 가져올 수 있습니다.

$('.hidden-element').get(0).height;

너비와 동일합니다.

$('.hidden-element').get(0).width;

(Skeets O'Reilly에게 감사를 표합니다)


반환undefined
Jake Wilson

1
이전에 페이지에 요소를 이미 표시 한 경우에만 작동합니다. 항상였던 요소의 display='none'경우 작동하지 않습니다.
스키트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.