|
|
|
| Здравствуйте, сообщество softtime!
в JavaScript разбираюсь очень поверхностно, поэтому прошу вашей помощи ткнуть меня носом.
Имеется код:
<html>
<head>
<script type="text/javascript">
function getRealDisplay(elem) {
if (elem.currentStyle) {
return elem.currentStyle.display
} else if (window.getComputedStyle) {
var computedStyle = window.getComputedStyle(elem, null )
return computedStyle.getPropertyValue('display')
}
}
function hide(el) {
if (!el.getAttribute('displayOld')) {
el.setAttribute("displayOld", el.style.display)
}
el.style.display = "none"
}
displayCache = {}
function isHidden(el) {
var width = el.offsetWidth, height = el.offsetHeight,
tr = el.nodeName.toLowerCase() === "tr"
return width === 0 && height === 0 && !tr ?
true : width > 0 && height > 0 && !tr ? false : getRealDisplay(el)
}
function toggle(el) {
isHidden(el) ? show(el) : hide(el)
}
function show(el) {
if (getRealDisplay(el) != 'none') return
var old = el.getAttribute("displayOld");
el.style.display = old || "";
if ( getRealDisplay(el) === "none" ) {
var nodeName = el.nodeName, body = document.body, display
if ( displayCache[nodeName] ) {
display = displayCache[nodeName]
} else {
var testElem = document.createElement(nodeName)
body.appendChild(testElem)
display = getRealDisplay(testElem)
if (display === "none" ) {
display = "block"
}
body.removeChild(testElem)
displayCache[nodeName] = display
}
el.setAttribute('displayOld', display)
el.style.display = display
}
}
</script>
<style>
.hidden1 { display: none }
</style>
</head>
<body>
<table border="1">
<tr>
<td onclick="javascript:toggle('hidden1')">Заголовок</td>
</tr>
<tr>
<td class="hidden1">Подзаголовок</td>
</tr>
<tr>
<td class="hidden1">Запись один</td>
</tr>
<tr>
<td class="hidden1">Запись два</td>
</tr>
<tr>
<td onclick="javascript:toggle('hidden2')">Заголовок №2</td>
</tr>
<tr>
<td class="hidden2">Подзаголовок №2</td>
</tr>
<tr>
<td class="hidden2">Запись один №2</td>
</tr>
<tr>
<td class="hidden2">Запись два №2</td>
</tr>
</table>
</body>
</html>
|
Пытаюсь сделать следующее:
имеется условный блок, в который включено Заголовок, Подзаголовок, Запись один, Запись два. Необходимо реализовать возможность скрытия/раскрытия блока при нажатии на Заголовок. При этом показан может быть только один блок, остальные в этот момент должны быть скрытыми.
Код js взят здесь. Никак не соображу как заставить его работать в связке с моей таблицей.
Или может если есть более простое решение подскажите.
Делаю именно для таблицы.
PS. В приведенном выше коде ничего не работает у меня. Блин, даже onclick не хочет ни на что реагировать... :((( js дается мне явно труднее чем php | |
|
|
|
|
|
|
|
для: Neverhood
(25.04.2012 в 13:05)
| | Я так понимаю, что для разных условных блоков должен быть свой style hidden, то есть нужно дополнительно используя javascript или php пробежаться по N-му количеству записей и присвоить им свои display:none (может в js это делается проще, не знаю). Это реализовать можно. Как с остальным-то быть? :) Кто-нибудь?
PS: количество условных блоков не ограничено каким-то одним количеством и формируется php-скриптом (к общему сведению). | |
|
|
|
|
|
|
|
для: Neverhood
(25.04.2012 в 14:20)
| | 1. Скрипт ваш здесь вообще не по делу. Он предназначен для обработки XML-документов (о чём свидетельствует используемое в скрипте свойство nodeName).
2. Таблица от прочих тегов отличается тем, что имеет связную структуру - положение и размеры каждой строки и ячейки зависят от положения и размеров ВСЕХ других строк и ячеек. Т.е. если измените свойства одной ячейки (например, добавите ей высоту) - это повлечёт изменение размеров всех ячеек строки. А изменение ширины одной ячейки может изменить ширину всех ячеек столбца.
3. Соответственно, даже в вашем "одностолбцовом" варианте выключение видимости ячейки с самым широким содержимым приведёт к общему уменьшению ширины всей таблицы (до значения следующей по ширине ячейки).
4. Ну а если же ваша таблица имеет несколько столбцов, то там вообще будет "кошмар в степени ужас". Запустите пример и посмотрите - что стало с положением ячеек и с бордерами:
<table border="1" cellpadding="10" cellspacing="0">
<tr><td>1Left</td><td>1Right</td></tr>
<tr><td style="display: none">2Left</td><td>2Right</td></tr>
<tr><td>3Left</td><td>3Right</td></tr>
</table>
|
-----
Я всё это не к тому, что "с таблицей сделать ничего нельзя", а к тому, что изменение свойства displaу - это не самый лучший вариант.
Совет: напишите обычный HTML-код для двух случаев: а) изначальное состояние таблицы и б) состояние таблицы после клика. Запустите оба кода поочередно в браузере и сделайте два скрина окна (нажатие кнопки PrintScreen и "вставка" в программе Paint с последующим сохранением файла в каком-либо из web-форматов). Прикрепите эти файлы к следующему сообщению, в котором опишите - на что именно вы как бы кликнули в первом скрине, чтобы получился второй скрин.
Уверен, что задача ваша решается самым простейшим образом.
И как только будет понятно - что именно вам надо - так сразу же многие из здесь присутствующих вам дадут код для решения этой задачи. В крайнем случае, если более желающих не найдётся, - я помогу. | |
|
|
|
|
 34.6 Кб |
|
|
для: ЯСА
(25.04.2012 в 20:36)
| | Спасибо, что откликнулись и огромное спасибо за содержательный и понятный ответ!
Прикрепляю скриншоты того, чего хочется добиться. То есть нажатием на бухгалтерию должен появится скрытый блок бухгалтерии с кабинетами и фамилиями сотрудников. Соответственно, если нажать отдел кадров, то блок бухгалтерии должен свернуться, а отдел кадров раскрыться (где только это не реализовано, почти на каждом сайте).
С блочными элементами типа div это действительно должно решаться наипростейшим способом (чувствую это :)), но увяз в таблицах и цепляюсь за них не замечая, возможно, элементарного решения...
И код.
before:
<html>
<head>
<style>
.title {
background-color: grey; color: #fff; text-align: center; width: 200px;
}
.subtitle {
font-size: 12px; background-color: #CACACA;
}
.surname {
text-align: center;
}
</style>
</head>
<body>
<table border="1">
<tr>
<td class="title">Бухгалтерия</td>
</tr>
<tr>
<td class="subtitle">Кабинет №1</td>
</tr>
<tr>
<td class="surname">Иванова А. П.</td>
</tr>
<tr>
<td class="surname">Козлова В. Я.</td>
</tr>
<tr>
<td class="subtitle">Кабинет №2</td>
</tr>
<tr>
<td class="surname">Петрушин Г. А.</td>
</tr>
<tr>
<td class="title">Отдел кадров</td>
</tr>
</table>
</body>
</html>
|
after:
<html>
<head>
<style>
.title {
background-color: grey; color: #fff; text-align: center; width: 200px;
}
.subtitle {
font-size: 12px; background-color: #CACACA;
}
.surname {
text-align: center;
}
</style>
</head>
<body>
<table border="1">
<tr>
<td class="title">Бухгалтерия</td>
</tr>
<tr>
<td class="title">Отдел кадров</td>
</tr>
<tr>
<td class="subtitle">Кабинет №3</td>
</tr>
<tr>
<td class="surname">Петренко В. А.</td>
</tr>
<tr>
<td class="subtitle">Кабинет №4</td>
</tr>
<tr>
<td class="surname">Теркина А. В.</td>
</tr>
<tr>
<td class="surname">Павлова З. М.</td>
</tr>
</table>
</body>
</html>
|
| |
|
|
|
|
 2.6 Кб |
|
|
для: Neverhood
(26.04.2012 в 00:01)
| | Ага... понятно, желающих нет.
-----
Несколько общих соображений:
1. При повторном клике на, например, уже ранее "открытую" "Бухгалтерию" надо её "закрыть".
Что приведет таблицу к изначальному виду, где будут только лишь наименования отделов.
Это как бы логично вытекает из практики пользования всевозможными гаджетами.
2. Не знаю, будут ли на вашей странице ещё какие-то таблицы, поэтому для однозначной
идентификации именно этой таблицы присвоил ей id="TBL"
3. Полагаю нужным принудительно установить размер и стиль шрифта в ячейках таблицы.
Попадётся плоховидящий, с дефолтным font-size: 36px - ширины в 200px ячейке не хватит.
4. Очевидно, что персон в таблице будет в сумме больше, чем кабинетов и названий отделов.
Для уменьшения веса кода класс "surname" ликвидирован, а его правила установлены для всех ячеек таблицы.
В двух других оставшихся классах эти правила "для всех ячеек" - отменены.
5. Чтобы не было "прыжков" контента, следующего за таблицей, запуск начального скрипта таблицы сделан
не после onload'а всего контента страницы, а сразу после закрывающего тега </table>.
Из этих же соображений таблице установлен нулевой начальный отступ снизу и прописан тег <BR> после таблицы.
(В прикрепленном коде после таблицы прописана горизонтальная линия <HR>,
коя при исполнении п. 5 должна быть неподвижной при любых состояниях таблицы).
-----
Теперь про скрипт: он состоит из двух функций: 1) предварительного оформления и 2) обработки клика.
Плюс сразу после закрывающего тега </table> - одна строка, запускающая первую функцию.
ПЕРВАЯ ФУНКЦИЯ (предварительная):
а) делает невидимыми все "кабинеты" и "персоны";
б) назначает "отделам" обработку клика второй функцией;
в) запускает вторую функцию для всех "отделов" по очереди с целью определения высоты для каждого открытого "отдела";
г) определяет среди этих высот максимальную и разницу между нею и каждой запоминает, чтобы назначать таблице снизу отступ;
д) исчисляет нужный отступ для таблицы только из "отделов", и прописывает его.
ВТОРАЯ ФУНКЦИЯ (обработка клика):
а) открывает "кабинеты+персоны" для "отдела" + делает отступ снизу и запоминает "отдел" до следующего клика;
б) если следующий клик будет по тому же "отделу", то она оставит в таблице только "отделы" (+ нужный отступ снизу);
в) если же следующий клик будет по иному "отделу", то закроет предыдущий и откроет нужный (+ нужный отступ снизу);
г) кроме всего, в функции реализован "первый проход", когда нужные отступы ещё только определяются.
-----
PS. Проверял в FF, Opera, Chrome.
MSIE сейчас под рукой нет.
А в нём обязательно что-либо "вылезет": в этом отношении MSIE - лучший валидатор.
Так что посмотрите в MSIE сами и отпишитесь о впечатлениях.
UPDATE: в MSIE 8 тоже всё нормально. | |
|
|
|
|
|
|
|
для: ЯСА
(26.04.2012 в 08:37)
| | Мог ли я подумать о таком ответе? Никогда! Вы же мне все расписали, да еще и весь код как на блюдечке. Мне аж неловко. Просил-то я о другом - ткнуть меня носом, а тут... Буду разбирать и изучать. Еще раз огромное спасибо за проделанную работу! | |
|
|
|
|
|
|
|
для: ЯСА
(26.04.2012 в 08:37)
| | Полезный код. Мне такой же очень нужен. | |
|
|
|
|
|
|
|
для: ЯСА
(26.04.2012 в 08:37)
| | Спасибо. | |
|
|
|
|
|
|
|
для: ЯСА
(26.04.2012 в 08:37)
| | Можно проще:
<style>
#tbl {
width: 400px;
border-collapse: separate;
}
#tbl td {
width: 100%;
border: 1px solid #999;
}
.head td {
background: #ddd;
cursor: pointer;
}
</style>
<script>
function toggle(e) {
if(e.tagName=='TD' && e.parentNode.className=='head') {
var row = document.getElementById('tbl').rows; e = e.parentNode;
for(i=0, k=row.length; i<k; i++) {
if(row[i].className == 'head') {
var mode = row[i] != e ? 1 : 0;
continue;
}
if(!row[i].style.display && mode) row[i].style.display = 'none';
else if(!mode) row[i].style.display == 'none' ? row[i].style.display = '' : row[i].style.display = 'none';
}
}
}
</script>
<table id="tbl" onclick="toggle(event.target || event.srcElement)">
<tr class="head">
<td>Заголовок</td>
</tr>
<tr style="display:none">
<td>Подзаголовок</td>
</tr>
<tr style="display:none">
<td>Запись один</td>
</tr>
<tr style="display:none">
<td>Запись два</td>
</tr>
<tr class="head">
<td>Заголовок №2</td>
</tr>
<tr style="display:none">
<td>Подзаголовок №2</td>
</tr>
<tr style="display:none">
<td>Запись один №2</td>
</tr>
<tr style="display:none">
<td>Запись два №2</td>
</tr>
</table>
|
| |
|
|
|
|
 402.1 Кб |
|
|
для: confirm
(12.10.2014 в 04:26)
| | Спасибо, оно работает. Только мне надо немного в другой структуре таблиц. В общем я разобрался, хоть и по другому, но не хватает такого элемента, чтобы, например ссылка, которая раскрывает то, что нужно, ещё скрывала всё остальное, что имеет изначальный style="dispay:none".
В архиве образец того, что нужно.
Но у меня пока что ссылки не убирают то, что было открыто другими ссылками. | |
|
|
|
|
|
|
|
для: Rivs29
(12.10.2014 в 16:52)
| | Ну так в этом случае надо еще же и индекс ячейки знать, этот индекс связывать с индексом строки текущей, а по нему уже и принимать решение. Изначально индекс ячейки активной можно "вынести за пределы":
<style>
#tbl {
width: 400px;
border-collapse: separate;
}
#tbl td {
border: 1px solid #999;
}
.head td {
background: #ddd;
cursor: pointer;
}
</style>
<script>
function toggle(e) {
if(e.tagName=='TD' && e.parentNode.className=='head') {
var row = document.getElementById('tbl').rows, tr = e.parentNode, cel = tr.cells, idx;
for(i=0, k=row.length; i<k; i++) {
if(row[i].className == 'head') {
for(j=0, n=cel.length; j<n; j++) {
if(tr==row[i] && cel[j] == e) {
idx = i+j+1;
break;
}
}
continue;
}
if(i != idx && !row[i].style.display) row[i].style.display = 'none';
else if(i == idx) row[idx].style.display == 'none' ? row[idx].style.display = '' : row[idx].style.display = 'none';
}
}
}
</script>
<table id="tbl" onclick="toggle(event.target || event.srcElement)">
<tr class="head">
<td>1</td><td>2</td><td>3</td>
</tr>
<tr style="display:none">
<td colspan="3">1-1</td>
</tr>
<tr style="display:none">
<td colspan="3">2-1</td>
</tr>
<tr style="display:none">
<td colspan="3">3-1</td>
</tr>
<tr class="head">
<td>4</td><td>5</td><td>6</td>
</tr>
<tr style="display:none">
<td colspan="3">4-1</td>
</tr>
<tr style="display:none">
<td colspan="3">5-1</td>
</tr>
<tr style="display:none">
<td colspan="3">6-1</td>
</tr>
<tr class="head">
<td>7</td><td>8</td><td>9</td>
</tr>
<tr style="display:none">
<td colspan="3">7-1</td>
</tr>
<tr style="display:none">
<td colspan="3">8-1</td>
</tr>
<tr style="display:none">
<td colspan="3">9-1</td>
</tr>
</table>
|
Вот только в вашем случае лучше все это сделать на чистом CSS+UL+LI, и только если нужны эффекты то JQ+UL+LI+DIV. | |
|
|
|
|
|
|
|
для: confirm
(12.10.2014 в 19:24)
| | Большое спасибо! Чудный код и всё замечательно работает, сам бы я такой код не написал. Насчёт ul+li я и не предположил, но и tr+td вполне подходит, то, что нужно. )))
Благодарю! | |
|
|
|
|
|
|
|
для: confirm
(12.10.2014 в 19:24)
| | А если я в td вставляю картинку, оно вроде уже не работает? | |
|
|
|
|
|
|
|
для: confirm
(12.10.2014 в 19:24)
| | Хотя если прописать background то работает, и это хорошо. | |
|
|
|
|
|
|
|
для: Rivs29
(13.10.2014 в 13:11)
| | Почему это не работает, все будет работать, обработка на любом элементе таблицы делегируется самой таблице, а функция проверяет по какому элементу произошел щелчок. Если перекрыть всю ячейку изображением, значит условие должно выполняться по тегу не TD, а IMG, а тег TR, который надо получить, будет не первым, а вторым по счету вверх. | |
|
|
|
|
|
|
|
для: confirm
(13.10.2014 в 13:26)
| | А как изменить код, если внутри каждой открывающей TD обязательно есть img? | |
|
|
|
|
|
|
|
для: Rivs29
(13.10.2014 в 14:41)
| | Изменяйте.
Условием начало цикла является:
if(e.tagName=='TD' && e.parentNode.className=='head')
Если ячейки заголовка, это будут картинки, значит условие должно быть:
if(e.tagName=='IMG' && e.parentNode.parentNode.className=='head')
Переменные:
e = e.parentNode; //теперь это ячейка
Все далее как и ранее.
var row = document.getElementById('tbl').rows, tr = e.parentNode, cel = tr.cells, idx;
.... | |
|
|
|