Так це відповідь?
"Якщо вам потрібно щось обчислити, але не показати, встановіть елемент 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) висота клієнта також була 0.
2) Дом фактично дав мені висоту, яка була великою.
3) ClientRects повертає результат, майже ідентичний техніці DOM.
Оскільки додані елементи мають рідкий характер, коли вони додаються до інакше порожнього елемента DOM Temp, вони надаються відповідно до ширини цього контейнера. Це стає дивно, тому що це на 30 пікселів коротше, ніж у підсумку.
Я додав кілька знімків, щоб проілюструвати, як висота обчислюється по-різному.
Перепади висот очевидні. Я, безумовно, можу додати абсолютне позиціонування та приховане, але впевнений, що це не матиме ефекту. Я продовжував переконатися, що це не вийде!
(Я відступаю далі) Висота виходить (робить) нижчою за справжню виведену висоту. Це можна вирішити, встановивши ширину елемента Temp DOM відповідно до існуючого батьківського, і це можна зробити досить точно теоретично. Я також не знаю, що може призвести до їх видалення та додавання назад у існуюче місце. Коли вони приїхали за допомогою методу InternalHTML, я буду дивитись, використовуючи цей інший підхід.
* ТАКОЖ * Нічого цього не було необхідним. Насправді він працював як рекламується і повертає правильну висоту !!!
Коли мені вдалося знову побачити меню, дивним чином DOM повернув правильну висоту на макет рідини вгорі сторінки (279 пікселів). Вищевказаний код також використовує getClientRects, які повертають 280px.
Це проілюстровано на наступному знімку (зробленому з Chrome колись працюючи.)
Тепер я не маю ідеї, чому цей трюк прототипу працює, але здається, що це. Крім того, getClientRects також працює.
Я підозрюю, що причиною всієї цієї проблеми з цими елементами було використання InternalHTML замість appendChild, але це є чистою міркуванням на даний момент.