Piszę stronę internetową, która ma tabelę z wierszami, które otwierają się i zamykają. Początkowo niektóre wiersze są zamknięte (display: none
) i chcę je zsunąć. Ustawienie wysokości i użycie overflow: hidden
nie działa w wierszach tabeli, więc zmieniam wysokość div wewnątrz tabeli.Jak znaleźć wysokość elementu, który nie jest wyświetlany
To działa. Jedynym problemem jest to, że muszę znać wysokość div, zanim go otworzę, co wydaje się niemożliwe. Jednym z rozwiązań, jakie mogę sobie wyobrazić, jest załadowanie strony z pokazem wierszy, a następnie iteracja po nich, przechowywanie ich wysokości i ich ukrywanie. Nie podoba mi się to rozwiązanie, ponieważ strona ładowała się podczas ładowania.
Oto prosty, działający przykład mojego problemu.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
table, td {border: 1px solid black;}
#lower_row {display: none;}
#lower_div {overflow: hidden;}
</style>
<script type="text/javascript">
function toggleLower() {
lowerRow = document.getElementById("lower_row");
lowerDiv = document.getElementById("lower_div");
if (getStyle(lowerRow, "display") == "none") {
lowerRow.style.display = "table-row";
}
else {
lowerRow.style.display = "none";
}
showHeight();
}
function showHeight() {
lowerDiv = document.getElementById("lower_div");
document.getElementById("info").innerHTML = getStyle(lowerDiv, "height");
}
// Return a style atribute of an element.
// J/S Pro Techniques p136
function getStyle(elem, name) {
if (elem.style[name]) {
return elem.style[name];
}
else if (elem.currentStyle) {
return elem.currentStyle[name];
}
else if (document.defaultView && document.defaultView.getComputedStyle) {
name = name.replace(/([A-Z])/g, "-$1");
name = name.toLowerCase();
s = document.defaultView.getComputedStyle(elem, "");
return s && s.getPropertyValue(name);
}
else {
return null;
}
}
</script>
</head>
<body onload="showHeight()">
<p>The height the lower row is currently <span id="info"></span></p>
<table>
<tr id="upper_row" onclick="toggleLower()"><td><p>Click me to toggle the next row.</p></td></tr>
<tr id="lower_row"><td><div id="lower_div"><p>Peekaboo!</p></div></td></tr>
</table>
</body>
</html>
Edit 1:
Jednym z proponowanych rozwiązań jest przenieść div poza stronę. Nie mogę tego zrobić, i myślę, że miałby złą wysokość, ponieważ jego wysokość zależy od szerokości stołu.
Pracuję nad rozwiązaniem użycia visibility:hidden
, ale ma problemy. Nadal zajmuje niewielką ilość miejsca, a podana wysokość jest błędna. Oto przykład tego rozwiązania:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
table {width: 250px;}
table, td {border: 1px solid black;}
#lower_row {position: absolute; visibility: hidden}
#lower_div {overflow: hidden;}
</style>
<script type="text/javascript">
function toggleLower() {
lowerRow = document.getElementById("lower_row");
lowerDiv = document.getElementById("lower_div");
if (getStyle(lowerRow, "visibility") == "hidden") {
lowerRow.style.visibility = "visible";
lowerRow.style.position = "static";
}
else {
lowerRow.style.visibility = "hidden";
lowerRow.style.position = "absolute";
}
showHeight();
}
function showHeight() {
lowerDiv = document.getElementById("lower_div");
document.getElementById("info").innerHTML = getStyle(lowerDiv, "height");
}
// Return a style atribute of an element.
// J/S Pro Techniques p136
function getStyle(elem, name) {
if (elem.style[name]) {
return elem.style[name];
}
else if (elem.currentStyle) {
return elem.currentStyle[name];
}
else if (document.defaultView && document.defaultView.getComputedStyle) {
name = name.replace(/([A-Z])/g, "-$1");
name = name.toLowerCase();
s = document.defaultView.getComputedStyle(elem, "");
return s && s.getPropertyValue(name);
}
else {
return null;
}
}
</script>
</head>
<body onload="showHeight()">
<p>The height the lower row is currently <span id="info"></span></p>
<table>
<tr id="upper_row" onclick="toggleLower()"><td><p>Click me to toggle the next row.</p></td></tr>
<tr id="lower_row"><td><div id="lower_div"><p>This is some long text. This is some long text. This is some long text. This is some long text.</p></div></td></tr>
</table>
</body>
</html>
Edit 2: odpowiedź roztworze
Pawła jest rozwiązaniem na moje pytanie: jak znaleźć wysokość elementu, który nie jest wyświetlany. Jednak nie zadziałałby na mój problem. W mojej witrynie wysokość div zależy od jego szerokości, która zależy od szerokości td, która zależy od stanu pozostałych wierszy i szerokości tabeli, która zależy od szerokości strony. Oznacza to, że nawet jeśli dokonam wstępnej obliczenia wysokości, wartość będzie nieprawidłowa, gdy tylko ktoś rozwinie inny wiersz lub zmieni rozmiar okna. Kopiowanie tabeli i utrzymywanie wszystkich tych ograniczeń byłoby prawie niemożliwe.
Jednak znalazłem rozwiązanie. Gdy użytkownik kliknie, aby rozwinąć wiersz, moja witryna wykona następujące kroki w kolejności:
- Ustaw wartość div.style.height na 1px.
- Ustaw wiersz.style.display na wiersz tabeli.
- Zapisz wartość div.scrollHeight.
- Uruchom animację przewijania, zatrzymując się na div.scrollHeight.
- Po animacji ustaw div.style.height na auto.
div.scrollHeight podaje wysokość zawartości div, łącznie z jej przepełnieniem. Nie działa, gdy element div nie jest wyświetlany, ale nie stanowi to problemu dla mojej aplikacji. Oto przykład kodu w akcji. (Ponownie, nie uwzględniam kodu animacji przewijania, ponieważ byłaby zbyt długa.)
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
table, td {border: 1px solid black;}
#lower_row {display: none;}
#lower_div {overflow: hidden;}
</style>
<script type="text/javascript">
function toggleLower() {
var lowerRow = document.getElementById("lower_row");
var lowerDiv = document.getElementById("lower_div");
if (getStyle(lowerRow, "display") == "none") {
lowerDiv.style.height = "0px";
lowerRow.style.display = "table-row";
showHeight();
lowerDiv.style.height = "auto";
}
else {
lowerDiv.style.height = "0px";
showHeight();
lowerRow.style.display = "none";
}
}
function showHeight() {
var lowerDiv = document.getElementById("lower_div");
document.getElementById("info").innerHTML = lowerDiv.scrollHeight;
}
// Return a style atribute of an element.
// J/S Pro Techniques p136
function getStyle(elem, name) {
if (elem.style[name]) {
return elem.style[name];
}
else if (elem.currentStyle) {
return elem.currentStyle[name];
}
else if (document.defaultView && document.defaultView.getComputedStyle) {
name = name.replace(/([A-Z])/g, "-$1");
name = name.toLowerCase();
s = document.defaultView.getComputedStyle(elem, "");
return s && s.getPropertyValue(name);
}
else {
return null;
}
}
</script>
</head>
<body>
<p>The height the lower row is currently <span id="info">...</span></p>
<table>
<tr id="upper_row" onclick="toggleLower()"><td><p>Click me to toggle the next row.</p></td></tr>
<tr id="lower_row"><td><div id="lower_div"><p>
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
This is some long text. This is some long text. This is some long text. This is some long text.
</p></div></td></tr>
</table>
</body>
</html>
co wydaje się być problemem? Twój html działa poprawnie. kiedy klikam wiersz, rozwijany jest poniższy wiersz. –
@vishal Aby zachować prostotę, mój przykład nie ma ruchomej animacji. Aby mieć animację ślizgową, muszę znać wysokość, zanim się rozszerzy. Jak pokazuje mój przykład, wysokość przed rozwinięciem jest "auto". – dln385
@ dln385 zobacz moją aktualizację w moim poście –