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

Найдите "потенциальную" ширину скрытого элемента

В настоящее время я расширяю lavalamp plugin для работы над выпадающими меню, но я столкнулся с небольшой проблемой. Мне нужно знать offsetWidth скрытого элемента. Теперь ясно, что этот вопрос не имеет смысла, скорее то, что я ищу, это offsetWidth элемента, если он не скрыт.

Это решение, чтобы показать его, захватить ширину, а затем снова спрятать? Должен быть лучший способ...

4b9b3361

Ответ 1

Единственное, что я могу придумать, это показать его (или его клон), чтобы разрешить поиск offsetWidth.

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

Ответ 2

Ширина элемента с CSS visibility: hidden измерима. Это только когда он display: none, что он вообще не отображается. Поэтому, если это определенно, элементы будут абсолютно позиционированы (поэтому они не вызывают изменение макета при отображении), просто используйте css('visibility', 'hidden'), чтобы скрыть свой элемент вместо hide(), и вы должны быть в порядке, измеряя ширину.

В противном случае да, show-measure-hide работает.

Ответ 3

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

$.fn.getHiddenOffsetWidth = function () {
    // save a reference to a cloned element that can be measured
    var $hiddenElement = $(this).clone().appendTo('body');

    // calculate the width of the clone
    var width = $hiddenElement.outerWidth();

    // remove the clone from the DOM
    $hiddenElement.remove();

    return width;
};

Вы можете изменить .outerWidth() на .offsetWidth() для своей ситуации.

Функция сначала клонирует элемент, копируя его в место, где оно будет видимым. Затем он извлекает ширину смещения и, наконец, удаляет клон. Следующий фрагмент иллюстрирует ситуацию, когда эта функция будет идеальной:

<style>
    .container-inner {
        display: none;
    }

    .measure-me {
        width: 120px;
    }
</style>

<div class="container-outer">
    <div class="container-inner">
        <div class="measure-me"></div>
    </div>
</div>

Помните, что если CSS применяется к элементу, который меняет ширину элемента, который не будет применяться, если он является прямым потомком тела, то этот метод не будет работать. Итак, что-то вроде этого будет означать, что функция не работает:

.container-outer .measure-me {
    width: 100px;
}

Вам нужно будет:

  • изменить спецификацию CSS-селектора, т.е. .measure-me { width: 100px; }
  • измените appendTo(), чтобы добавить клон в место, где ваш CSS также будет применен к клону. Убедитесь, что где бы вы его ни разместили, элемент будет виден: .appendTo('.container-outer')

Опять же, эта функция предполагает, что элемент скрыт только потому, что он находится внутри скрытого контейнера. Если сам элемент display:none, вы можете просто добавить некоторый код, чтобы сделать клон видимым до того, как вы получите его ширину смещения. Что-то вроде этого:

$.fn.getHiddenOffsetWidth = function () {
    var hiddenElement $(this)
        width = 0;

    // make the element measurable
    hiddenElement.show();

    // calculate the width of the element
    width = hiddenElement.outerWidth();

    // hide the element again
    hiddenElement.hide();

    return width;
}

Это будет работать в такой ситуации:

<style>
    .measure-me {
        display: none;
        width: 120px;
    }
</style>

<div class="container">
    <div class="measure-me"></div>
</div>

Ответ 4

Два варианта:

  • поместите элемент за пределы области просмотра (например: left:-10000px)
  • используйте visibility: hidden или opacity: 0 вместо hide().

В любом случае это будет работать как скрытие элемента, но все же возможность получить вычисленную ширину. Будьте осторожны с Safari на thi, это ужасно быстро, а иногда и слишком быстро...

Ответ 5

Фактический плагин jQuery!

Применение:

console.log('width without actual: ' + $('#hidden').width());

console.log('width with actual: ' + $('#hidden').actual('width'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.actual/1.0.19/jquery.actual.min.js"></script>

<div style="width: 100px; display: none;">
  <div id="hidden"></div>
</div>

Ответ 6

thats, потому что его скрытый через display: none; Что было сделано в прошлом, так это сделать "приемник", который я использую для абсолютного позиционирования, чтобы вытащить его из страницы. Затем я загружаю новый элемент в это, захватываю размеры и затем удаляю его, когда он сделан - затем удаляйте приемник, когда он сделан.

Еще одна вещь, которую вы можете сделать, - не использовать hide(); но вместо этого установить видимость: hidden; display:; Однако это означает, что пустая область будет отображаться везде, где прикреплен node.

Ответ 7

Я пытаюсь найти рабочую функцию для скрытого элемента, но я понимаю, что 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

demo: http://jsbin.com/ETiGIre/7

Ответ 8

Я сделал это; к тому времени скрывая этот элемент, сохранил свою ширину в своем наборе данных. Он будет работать только для вас, если вы можете скрыть программно.

т.

При скрытии

var elem = $("selectorOfElement");

elem.dataset.orgWidth = elem.clientWidth;

Позже при получении;

var elem = $("selectorOfElement");

var originalWidthWas = elem.dataset.orgWidth;