Найдите "потенциальную" ширину скрытого элемента
В настоящее время я расширяю lavalamp plugin для работы над выпадающими меню, но я столкнулся с небольшой проблемой. Мне нужно знать offsetWidth
скрытого элемента. Теперь ясно, что этот вопрос не имеет смысла, скорее то, что я ищу, это offsetWidth
элемента, если он не скрыт.
Это решение, чтобы показать его, захватить ширину, а затем снова спрятать? Должен быть лучший способ...
Ответы
Ответ 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;