Так это ответ?
"Если вам нужно что-то вычислить, но не показать, установите элемент на visibility:hidden
и position:absolute
, добавьте его в дерево DOM, получите offsetHeight и удалите его. (Это то, что делает библиотека прототипов строки в прошлый раз, когда я проверял). "
У меня та же проблема с рядом элементов. На сайте нет ни jQuery, ни прототипов, но я полностью поддерживаю заимствование техники, если она работает. В качестве примера некоторых вещей, которые не работали, после чего я сделал следующий код:
// Layout Height Get
function fnElementHeightMaxGet(DoScroll, DoBase, elementPassed, elementHeightDefault)
{
var DoOffset = true;
if (!elementPassed) { return 0; }
if (!elementPassed.style) { return 0; }
var thisHeight = 0;
var heightBase = parseInt(elementPassed.style.height);
var heightOffset = parseInt(elementPassed.offsetHeight);
var heightScroll = parseInt(elementPassed.scrollHeight);
var heightClient = parseInt(elementPassed.clientHeight);
var heightNode = 0;
var heightRects = 0;
//
if (DoBase) {
if (heightBase > thisHeight) { thisHeight = heightBase; }
}
if (DoOffset) {
if (heightOffset > thisHeight) { thisHeight = heightOffset; }
}
if (DoScroll) {
if (heightScroll > thisHeight) { thisHeight = heightScroll; }
}
//
if (thisHeight == 0) { thisHeight = heightClient; }
//
if (thisHeight == 0) {
// Dom Add:
// all else failed so use the protype approach...
var elBodyTempContainer = document.getElementById('BodyTempContainer');
elBodyTempContainer.appendChild(elementPassed);
heightNode = elBodyTempContainer.childNodes[0].offsetHeight;
elBodyTempContainer.removeChild(elementPassed);
if (heightNode > thisHeight) { thisHeight = heightNode; }
//
// Bounding Rect:
// Or this approach...
var clientRects = elementPassed.getClientRects();
heightRects = clientRects.height;
if (heightRects > thisHeight) { thisHeight = heightRects; }
}
//
// Default height not appropriate here
// if (thisHeight == 0) { thisHeight = elementHeightDefault; }
if (thisHeight > 3000) {
// ERROR
thisHeight = 3000;
}
return thisHeight;
}
, который в основном пытается что-нибудь и все, только чтобы получить нулевой результат. ClientHeight без каких-либо последствий. С проблемными элементами я обычно получаю NaN в базе и ноль в высотах смещения и прокрутки. Затем я попытался добавить решение DOM и clientRects, чтобы посмотреть, работает ли оно здесь.
29 июня 2011 г.,
Я действительно обновил код, чтобы попробовать добавить DOM и clientHeight с лучшими результатами, чем я ожидал.
1) clientHeight также был равен 0.
2) Дом на самом деле дал мне высоту, которая была великолепна.
3) ClientRects возвращает результат, почти идентичный методу DOM.
Поскольку добавленные элементы являются текучими по своей природе, когда они добавляются к в противном случае пустому элементу Temp DOM, они отображаются в соответствии с шириной этого контейнера. Это странно, потому что это на 30 пикселей короче, чем в итоге получается.
Я добавил несколько снимков, чтобы проиллюстрировать, как высота рассчитывается по-разному.
Различия в высоте очевидны. Я, конечно, мог бы добавить абсолютное позиционирование и скрытое, но я уверен, что это не будет иметь никакого эффекта. Я продолжал убеждаться, что это не сработает!
(отступаю дальше) Высота получается (отображается) ниже, чем истинная отображаемая высота. Эту проблему можно решить, установив ширину элемента DOM Temp в соответствии с существующим родителем, и теоретически это можно сделать довольно точно. Я также не знаю, что произойдет, если удалить их и добавить обратно в их существующее местоположение. Поскольку они пришли через метод innerHTML, я буду искать, используя этот другой подход.
* ОДНАКО * Ничего из этого не было необходимо. Фактически это работало как рекламировалось и возвратило правильную высоту !!!
Когда я смог снова удивительно увидеть меню, DOM вернул правильную высоту в соответствии с макетом флюида в верхней части страницы (279 пикселей). Приведенный выше код также использует getClientRects, которые возвращают 280px.
Это показано на следующем снимке (взято из Chrome после работы.)
Теперь у меня нет идеи, почему этот трюк с прототипом работает, но, похоже, это так. Кроме того, getClientRects также работает.
Я подозреваю, что причиной всех этих проблем с этими конкретными элементами было использование innerHTML вместо appendChild, но на данный момент это чистое предположение.