source

jQuery - 보이지 않을 때 요소 너비 가져오기(표시:없음)

ittop 2023. 8. 10. 21:30
반응형

jQuery - 보이지 않을 때 요소 너비 가져오기(표시:없음)

요소가 보이지 않는 너비()일 때 jQuery에서 0을 반환하는 것 같습니다.일리가 있지만 부모를 표시하기 전에 부모의 너비를 설정하려면 테이블의 너비를 가져와야 합니다.

아래에서 설명한 것처럼 부모에 텍스트가 있어 부모가 왜곡되어 보기 흉하게 보입니다.저는 부모님이 테이블 너비만큼만 되고 텍스트 랩을 하기를 원합니다.

<div id="parent">
    Text here ... Can get very long and skew the parent
    <table> ... </table>
    Text here too ... which is why I want to shrink the parent based on the table
</div>

CSS:

#parent
{
    display: none;
}

Javascript:

var tableWidth = $('#parent').children('table').outerWidth();
if (tableWidth > $('#parent').width())
{
    $('#parent').width(tableWidth);
}

tableWidth는 보이지 않기 때문에 항상 0을 반환합니다(표시될 때 번호를 알려주기 때문에 제 추측입니다).부모를 보이지 않게 하지 않고 테이블의 너비를 얻는 방법이 있습니까?

여기 제가 사용한 속임수가 있습니다.일부 CSS 속성을 추가하여 jQuery가 요소를 볼 수 있다고 생각하게 하지만 실제로는 여전히 숨겨져 있습니다.

var $table = $("#parent").children("table");
$table.css({ position: "absolute", visibility: "hidden", display: "block" });
var tableWidth = $table.outerWidth();
$table.css({ position: "", visibility: "", display: "" });

그것은 일종의 해킹이지만, 저에게는 잘 작동하는 것 같습니다.

갱신하다

그 이후로 저는 이 주제를 다루는 블로그 게시물을 작성했습니다.위에서 사용한 방법은 CSS 속성을 빈 값으로 재설정하기 때문에 문제가 될 수 있습니다.만약 그들이 이전에 가치관을 가지고 있었다면 어땠을까요?업데이트된 솔루션은 jQuery 소스 코드에 있는 swap() 메서드를 사용합니다.

참조된 블로그 게시물의 코드:

//Optional parameter includeMargin is used when calculating outer dimensions  
(function ($) {
$.fn.getHiddenDimensions = function (includeMargin) {
    var $item = this,
    props = { position: 'absolute', visibility: 'hidden', display: 'block' },
    dim = { width: 0, height: 0, innerWidth: 0, innerHeight: 0, outerWidth: 0, outerHeight: 0 },
    $hiddenParents = $item.parents().andSelf().not(':visible'),
    includeMargin = (includeMargin == null) ? false : includeMargin;

    var oldProps = [];
    $hiddenParents.each(function () {
        var old = {};

        for (var name in props) {
            old[name] = this.style[name];
            this.style[name] = props[name];
        }

        oldProps.push(old);
    });

    dim.width = $item.width();
    dim.outerWidth = $item.outerWidth(includeMargin);
    dim.innerWidth = $item.innerWidth();
    dim.height = $item.height();
    dim.innerHeight = $item.innerHeight();
    dim.outerHeight = $item.outerHeight(includeMargin);

    $hiddenParents.each(function (i) {
        var old = oldProps[i];
        for (var name in props) {
            this.style[name] = old[name];
        }
    });

    return dim;
}
}(jQuery));
function realWidth(obj){
    var clone = obj.clone();
    clone.css("visibility","hidden");
    $('body').append(clone);
    var width = clone.outerWidth();
    clone.remove();
    return width;
}
realWidth($("#parent").find("table:first"));

로버츠의 답변을 토대로, 제 기능은 이렇습니다.이것은 요소 또는 부모가 jQuery를 통해 페이드아웃된 경우에 사용할 수 있으며 내부 또는 외부 치수를 가져올 수 있으며 오프셋 값도 반환합니다.

/edit1: 함수를 다시 썼습니다.이제 크기가 작아졌고 객체에서 직접 호출할 수 있습니다.

/edit2: 함수는 이제 본문 대신 원래 요소 바로 뒤에 클론을 삽입하여 클론이 상속된 차원을 유지할 수 있도록 합니다.

$.fn.getRealDimensions = function (outer) {
    var $this = $(this);
    if ($this.length == 0) {
        return false;
    }
    var $clone = $this.clone()
        .show()
        .css('visibility','hidden')
        .insertAfter($this);        
    var result = {
        width:      (outer) ? $clone.outerWidth() : $clone.innerWidth(), 
        height:     (outer) ? $clone.outerHeight() : $clone.innerHeight(), 
        offsetTop:  $clone.offset().top, 
        offsetLeft: $clone.offset().left
    };
    $clone.remove();
    return result;
}

var dimensions = $('.hidden').getRealDimensions();

위에 realWidth 기능을 올려주셔서 감사합니다, 정말 도움이 되었습니다.위의 "realWidth" 함수를 기반으로 CSS 재설정(아래 설명된 이유)을 작성했습니다.

function getUnvisibleDimensions(obj) {
    if ($(obj).length == 0) {
        return false;
    }

    var clone = obj.clone();
    clone.css({
        visibility:'hidden',
        width : '',
        height: '',
        maxWidth : '',
        maxHeight: ''
    });
    $('body').append(clone);
    var width = clone.outerWidth(),
        height = clone.outerHeight();
    clone.remove();
    return {w:width, h:height};
}

"realWidth"는 기존 태그의 너비를 가져옵니다.저는 이것을 이미지 태그로 테스트했습니다.문제는 이미지가 너비(또는 최대 너비)당 CSS 치수를 제공할 때 해당 이미지의 실제 치수를 결코 얻을 수 없다는 것입니다.아마도 img에는 "최대 너비: 100%"가 있고, "실제 너비" 함수는 이를 복제하여 신체에 추가합니다.이미지의 원래 크기가 몸보다 크면 실제 이미지의 크기가 아니라 몸의 크기가 됩니다.

숨겨진 무언가의 너비가 필요하고 어떤 이유로든 숨길 수 없다면, 그것을 복제하고, CSS를 변경하여 페이지에 표시되도록 하고, 보이지 않게 한 다음 측정할 수 있습니다.나중에 숨겼다가 삭제해도 사용자는 알 수 없습니다.

여기에 있는 다른 답변들 중 일부는 가시성을 숨겨놓지만, 어느 것이 효과적인지는 잠시 동안 페이지의 빈 자리를 차지합니다.

예:

$itemClone = $('.hidden-item').clone().css({
        'visibility': 'hidden',
        'position': 'absolute',
        'z-index': '-99999',
        'left': '99999999px',
        'top': '0px'
    }).appendTo('body');
var width = $itemClone.width();
$itemClone.remove();

저는 숨겨진 요소에 대한 작동 기능을 찾으려고 노력하지만 CSS가 모두가 생각하는 것보다 훨씬 복잡하다는 것을 깨달았습니다.CSS3에는 유연한 상자, 그리드, 열 또는 복잡한 상위 요소 내부의 요소와 같은 이전의 모든 답변에 대해 작동하지 않을 수 있는 새로운 레이아웃 기술이 많이 있습니다.

유연성 상자 예제 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
});

자세한 내용은 제 프로젝트 깃허브에서 확인하시기 바랍니다.

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

데모: http://jsbin.com/ETiGIre/7

너비를 측정하기 전에 부모 디스플레이를 표시한 다음 너비를 측정하여 마지막으로 부모 디스플레이를 숨깁니다.따라하는 것처럼.

$('#parent').show();
var tableWidth = $('#parent').children('table').outerWidth();
 $('#parent').hide();
if (tableWidth > $('#parent').width())
{
    $('#parent').width() = tableWidth;
}

한 가지 해결책은 모든 상황에서 작동하지는 않지만 불투명도를 0으로 설정하여 요소를 숨기는 것입니다.완전히 투명한 요소에는 너비가 있습니다.

단점은 요소가 여전히 공간을 차지하지만 모든 경우에 문제가 되지는 않는다는 것입니다.

예:

$(img).css("opacity", 0)  //element cannot be seen
width = $(img).width()    //but has width

여기서 대부분의 솔루션이 놓치는 가장 큰 문제는 요소의 너비가 종종 HTML의 범위를 기준으로 CSS에 의해 변경된다는 것입니다.

현재 범위에만 적용되는 스타일이 있을 때 요소의 복제본을 본문에 추가하여 요소의 오프셋 너비를 결정하면 잘못된 너비를 얻을 수 있습니다.

예:

//수정

.vmdk-mdk.my-emlem{ 테두리: 60인치 솔리드 블랙; }

이제 제가 몸의 맥락에서 제-엘렘의 너비를 결정하려고 하면 120px만큼 나올 것입니다.대신 모듈 컨테이너를 복제할 수 있지만 JS가 이러한 세부 정보를 알 필요는 없습니다.

테스트를 해보지는 않았지만 Soul_Master의 솔루션이 제대로 작동할 수 있는 유일한 솔루션인 것 같습니다.그러나 안타깝게도 구현을 살펴보면 사용 비용이 많이 들고 성능에 악영향을 미칠 수 있습니다(여기에 제시된 대부분의 솔루션도 마찬가지임).

가능하면 가시성(숨김)을 대신 사용합니다.이렇게 하면 요소가 렌더링되므로 큰 문제 없이 너비를 계산할 수 있습니다.

뱅크스가 올린 답변 외에도 제 문제를 해결하기 위해 한 가지 간단한 것을 편집해야 했습니다.

다른 사용자도 동일한 문제를 가지고 있을 수 있습니다. 저는 드롭다운에 있는 부트스트랩 드롭다운으로 작업하고 있습니다.그러나 텍스트는 현 시점에서 현재 콘텐츠만큼 더 넓어질 수 있습니다(그리고 CSS를 통해 그것을 해결할 수 있는 좋은 방법은 많지 않습니다).

사용:

$table.css({ position: "absolute", visibility: "hidden", display: "table" });

대신 내용물이 더 넓은 경우 항상 너비로 조정되는 테이블로 컨테이너를 설정합니다.

jQuery(".megamenu li.level0 .dropdown-container .sub-column ul .level1").on("mouseover", function () {
    var sum = 0;
    jQuery(this).find('ul li.level2').each(function(){
    sum -= jQuery(this).height();
    jQuery(this).parent('ul').css('margin-top', sum / 1.8);
    console.log(sum);
    });
});

호버에서 목록 항목 높이를 계산할 수 있습니다.

앞에서 언급한 것처럼 다른 곳에서 복제 및 첨부 방법이 스타일이 다를 수 있으므로 동일한 결과를 보장하지는 않습니다.

제 접근법은 다음과 같습니다.그것은 부모들을 위로 이동하여 숨긴 부모를 찾은 다음, 필요한 너비, 높이 등을 계산하기 위해 일시적으로 그것을 해제합니다.

    var width = parseInt($image.width(), 10);
    var height = parseInt($image.height(), 10);

    if (width === 0) {

        if ($image.css("display") === "none") {

            $image.css("display", "block");
            width = parseInt($image.width(), 10);
            height = parseInt($image.height(), 10);
            $image.css("display", "none");
        }
        else {

            $image.parents().each(function () {

                var $parent = $(this);
                if ($parent.css("display") === "none") {

                    $parent.css("display", "block");
                    width = parseInt($image.width(), 10);
                    height = parseInt($image.height(), 10);
                    $parent.css("display", "none");
                }
            });
        }
    }

언급URL : https://stackoverflow.com/questions/1472303/jquery-get-width-of-element-when-not-visible-display-none

반응형