|
|
|
| Сделал примерный алгоритм функции спойлера открывающей блок, но запустить не могу.
Хочу узнать правильный ли вообще алгоритм, если да то как его довести до работоспособности, а если нет, то что я не учел и в каком направлении двигаться.
Спасибо.
<script language="javascript">
function ge(id)
{
return document.getElementById(id);
}
// функция раскрытия блока
function show(id)
{
var show_step = 20; // шаг px
var show_time_interval = 20; // период времени ms
ge(id).style.display = 'block';
// функция изменения высоты блока за еденицу времени
function resize(id)
{
// прибавляем к текущей высоте блока шаг
var temp_height = ge(id).height + show_step;
// если еще не раскрылся полностью
if (temp_height <= ge(id).offsetHeight)
{
// применяем изменения
ge(id).height = temp_height+'px';
}
else
{
// если же раскрылся
ge(id).height = ge(id).offsetHeight;
// завершение работы скрипта
return;
}
}
setTimeout(resize(id), show_time_interval);
}
</script>
<a href="#" onclick="show('cr');return false;">Показать скрытый текст плавно</a>
<div id="cr" style="display:none;">Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст</div>
|
| |
|
|
|
|
|
|
|
|
для: АЯ
(19.05.2010 в 15:44)
| | Спасибо за ссылки | |
|
|
|
|
|
|
|
для: АЯ
(19.05.2010 в 15:44)
| | Появилась еще одна заморочка - со стасусами положения блока.
Вызываю функцию show(id) - блок раскрывается, вызываю hide(id) - сворачивается и механизм перестает работать.
А хочу вообще надо так:
вызываем show(), блок в процессе разворачивания, если не дождавшись полного раскрытия вызывается hide(), то hide() останавливает раскрытие блока и начинает его обратно сворачивать, начиная с тех координат, где была вызвана hide()
// 0 - панель полностью свёрнута, доступна для разворачивания
// 1 - панель в процессе разворачивания, недоступна для разворачивания, доступна для сворачивания
// 2 - панель полностью развёрнута, доступна только для сворачивания
// 3 - панель в процессе сворачивания, недоступна для разворачивания
любой блок считается свернутым, если не достиг статуса 2
<script language="javascript">
function ge(id)
{
return document.getElementById(id);
}
function show(id)
{
if (this.st == 1) return false;
var obj = ge(id);
obj.style.display = 'block';
this.maxh = obj.offsetHeight;
obj.style.display = 'none';
function resize_s()
{
if (obj.offsetHeight >= this.maxh) {obj.style.height = this.maxh; this.st = 2;}
else
{
this.st = 1;
var h = obj.offsetHeight + 13;
obj.style.height = h + 'px';
setTimeout(resize_s, 3);
}
}
resize_s();
obj.style.display = 'block';
}
function hide(id)
{
if (this.st == 3) return false;
var obj = ge(id);
function resize_h()
{
if (obj.offsetHeight <= 0) {obj.style.height = 0; this.st = 0;}
else
{
this.st = 3;
var h = obj.offsetHeight - 13;
obj.style.height = h + 'px';
setTimeout(resize_h, 3);
}
}
resize_h();
obj.style.display = 'hidden';
}
</script>
<a href="#" style="" onclick="show('cr');return false;">Показать</a><br>
<a href="#" style="" onclick="hide('cr');return false;">скрыть</a>
<div id="cr" style="overflow:hidden;display:none;background-color:#EEEEEE;width:500px;">
Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>
Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>
Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст<br>Текст</div> Текст
|
| |
|
|
|
|
|
|
|
для: Рома
(21.05.2010 в 14:31)
| | У Вас не определена переменная this ни в одной из функций.
Что такое this, и чему равно this.st - никто не знает.
Браузер - тоже не знает. | |
|
|
|
|
|
|
|
для: АЯ
(21.05.2010 в 16:37)
| | А нужен ли мне вообще статус для вот такого?
<body onload="ge('cr').innerHTML='Текст по умолчанию';show('cr');return false;">
<a href="#" onclick="hide('cr');ge('cr').innerHTML='Текст параграфа 1';show('cr');return false;">Параграф 1</a>
<a href="#" onclick="hide('cr');ge('cr').innerHTML='Текст параграфа 2';show('cr');return false;">Параграф 2</a>
<a href="#" onclick="hide('cr');ge('cr').innerHTML='Текст параграфа 3';show('cr');return false;">Параграф 3</a>
<a href="#" onclick="hide('cr');ge('cr').innerHTML='Текст параграфа 4';show('cr');return false;">Параграф 4</a>
<div id="cr" style="overflow:hidden;display:none;background-color:#EEEEEE;width:500px;"></div>
|
что такое this я и сам не знаю. В этом коде он лишь избавляет от необходимости передавать в функцию resize_s() переменную конечной высоты. Узнал об этом методом научного тыка.
function show(id)
{
var obj = ge(id);
obj.style.display = 'block';
this.maxh = obj.offsetHeight;
obj.style.display = 'none';
function resize_s()
{
if (obj.offsetHeight >= this.maxh) {obj.style.height = this.maxh;}
else
{
var h = obj.offsetHeight + 13;
obj.style.height = h + 'px';
setTimeout(resize_s, 3);
}
}
resize_s();
obj.style.display = 'block';
}
|
| |
|
|
|
|
|
|
|
для: АЯ
(21.05.2010 в 16:37)
| | Вобще на яве можно все что угодно сделать или нет?
А то свернув блок и подставив в него новый текст, с новым текстом блок разворачивается на туже высоту, что и со старым текстом, независимо от того меньше там текста или больше. И не так обидно, что механизм мне пока не дается, как то, что высота никак не хочет изменяться, а это важнее всего, иначе нет смысла и спойлером заниматься. | |
|
|
|
|
|
|
|
для: Рома
(21.05.2010 в 20:45)
| |
<html>
<head>
<style>
span.ButToN {cursor: pointer; text-decoration: underline}
div.ShowHide {margin: 5px 0; overflow: hidden; height: 1px}
</style>
<script>
function fDelay (ev) {
var EVT = window.event || ev, BTN = EVT.target || EVT.srcElement, STS = (BTN.innerHTML == 'Show');
BTN.innerHTML = (STS) ? 'Hide' : 'Show'; BTN.lang = (STS) ? 1 : -1; if (!self.TMR) fMove ()}
function fMove () {
var j = 0; while (document.getElementById ('btn_' + j)) {
var BTN = document.getElementById ('btn_' + j), PNL = document.getElementById ('pnl_' + j);
var HEI = PNL.offsetHeight; HEI += BTN.lang * 1;
if (HEI > 1 && HEI < PNL.scrollHeight) PNL.style.height = HEI + 'px'; j++} TMR = setTimeout (fMove, 123)}
</script>
</head>
<body>
<hr>
<span class="ButToN" onclick="fDelay (event)" id="btn_0">Show</span>
<div class="ShowHide" id="pnl_0">a<br>b<br>c<br>d</div>
<hr>
<span class="ButToN" onclick="fDelay (event)" id="btn_1">Show</span>
<div class="ShowHide" id="pnl_1">e<br>f<br>g<br>h</div>
<hr>
<span class="ButToN" onclick="fDelay (event)" id="btn_2">Show</span>
<div class="ShowHide" id="pnl_2">i<br>j<br>k<br>l</div>
<hr>
</body>
</html>
|
1. Кнопок "Показать/Скрыть" и соответствующих им контейнеров может быть сколь угодно много.
2. Кнопки и контейнеры должны быть пронумерованы по показанному выше принципу. НАЧИНАЯ С НУЛЕВОЙ И БЕЗ РАЗРЫВОВ В НУМЕРАЦИИ. Т.е. следующая кнопка должна иметь именно id="btn_3", но не id="btn_4"
3. Динамически изменять высоту любого контейнера можно как угодно. Открываться будет именно на текущую высоту. Что можете проверить, вставив в код тестовую кнопку
<input type="button" value="TEST" onclick="for (var s = [], j = 0; j < 20; j++) s [j] = j;
document.getElementById ('pnl_1').innerHTML = s.join ('<br>')">
|
4. Скорость открывания/закрывания регулируйте целым числом - сейчас установлено 123 миллисекунды, что соответствует скорости 1/123 пиксела в миллисекунду.
5. Кнопки и соответствующие им контейнеры НЕ ОБЯЗАТЕЛЬНО должны находиться в HTML-коде один под другим. | |
|
|
|
|
|
|
|
для: АЯ
(21.05.2010 в 22:52)
| | Даже не знаю что и ответить)))
Давайте я заработаю денег, тогда и обращусь к вам - и мне будет не стыдно сказать, что немножко не так, и у вас будет интерес, хорошо? А то кроме вас я не знаю ни кого, кто пишет js не прибегая к jquery.
А по поводу кода, объясню почему мне это не подходит: я готов содержать любую необходимую информацию о спойлере хоть даже в переменной сессии, только чтобы функции спойлера были отвязаны от id обрабатываемого блока. По другому мое приложение не заработает, т.к. я никогда не знаю какой id будет открываться/сворачиваться в следующий раз и какое в нем будет содержимое - все id уникальные и генерируются динамически по мере добавления/изменения информации. А разбив функцию спойлера на show и hide я обрежу пользователю возможность самостоятельно управлять контентом - в моем случае спойлер должен быть не удобством, а интерфейсом представления данных. | |
|
|
|
|
|
|
|
для: Рома
(22.05.2010 в 01:05)
| | 1. минимальная (начальная) высота контейнера должна быть 1px (ноль некоторые браузеры не понимают). Отсюда - контейнеру следует задать изначально не только стиль height: 1px, но и стиль overflow: hidden, чтобы он нормально отображался при малых высотах.
2. установка (write) новой высоты контейнера (при его развёртывании/сворачивании) осуществляется посредством прописывания
контейнер.style.height = новая_высота + 'px';
|
3. узнавать (read) текущую высоту контейнера (при его развёртывании/сворачивании) надо через
искомое = контейнер.offsetHeight
|
4. узнавать (read) максимальную высоту контейнера (зависящую от текущего содержимого) следует через
искомое = контейнер.scrollHeight
|
ТАКИМ ОБРАЗОМ
При развёртывании:
а) узнаем текущую высоту (см. п.3)
б) сравниваем её с максимальной (см. п.4)
в) если текущая высота меньше максимальной, то устанавливаем контейнеру новую, увеличенную на единицу, высоту (см. п.2). Если текущая высота равна максимальной, развёртывание прекращаем.
При сворачивании:
г) узнаем текущую высоту (см. п.3)
д) сравниваем её с минимальной единицей (см. п.1)
е) если текущая высота больше единицы, то устанавливаем контейнеру новую, уменьшенную на единицу, высоту (см. п.2). Если текущая высота равна единице, сворачивание прекращаем.
Этот механизм ясен?
----------------------------------
Хотите иметь две отдельные кнопки для развёртывания/сворачивания и не хотите иметь зависимости значений id кнопок и контейнеров ни друг от друга, ни в пределах всего документа - нет проблем.
I. Положим, динамически появляются две кнопки <SPAN>Развернуть</SPAN>, <SPAN>Свернуть</SPAN> и контейнер <DIV>Содержимое</DIV>, содержимое которого они и должны развернуть/свернуть.
II. По-любому, кнопки "Развернуть" и "Свернуть" должны иметь информацию о конкретном контейнере. Значит, контейнер должен иметь свой уникальный id, а обе кнопки должны иметь информацию об этом id. Следовательно, по-любому, при динамическом появлении трёх этих объектов они должны иметь, как минимум, следующий вид:
<DIV id="myId">Содержимое</DIV>
<SPAN onclick="funcShow ('myID')">Развернуть</SPAN>
<SPAN onclick="funcHide ('myID')">Свернуть</SPAN>
|
III. Как уже Вам известно (см. п.1), все контейнеры должны иметь изначально предустановленные высоту в один пиксел и скрытый скролл overflow: hidden. Что вполне можно оформить одним классом в стилях.
Вам ничего не помешает прописать одно и то же имя класса для ВСЕХ Ваших контейнеров, как имеющихся, так и динамически появившихся?
Т. е. сделать так:
<DIV id="myId" class="myStandartClass">Содержимое</DIV>
<SPAN onclick="funcShow ('myID')">Развернуть</SPAN>
<SPAN onclick="funcHide ('myID')">Свернуть</SPAN>
| и, соответственно, для любых ДРУГИХ "связок" "кнопка+кнопка+контейнер" иметь следующую структуру:
<DIV id="myIdOther1357" class="myStandartClass">ДРУГОЕ содержимое</DIV>
<SPAN onclick="funcShow ('myIdOther1357')">Развернуть</SPAN>
<SPAN onclick="funcHide ('myIdOther1357')">Свернуть</SPAN>
|
IV. Если на выделенный жирно вопрос в п.III отвечаете положительно, то проблема Ваша решается элементарно. И я Вам помогу сразу.
Если я чего-то недопонял, то напишите - что именно Вам надо.
Мей би, Вы хотите иметь на странице всего ДВЕ кнопки Развернуть/Свернуть, а контейнеров у Вас будет десяток - при этом эти контейнеры у Вас будут появляться не по одному (взамен предыдущего) на странице, а сразу по пять (и все пять надо будет развертывать/свертывать одним нажатием одной кнопки)? | |
|
|
|
|
 1.4 Кб |
|
|
для: АЯ
(22.05.2010 в 13:03)
| | >Вам ничего не помешает прописать одно и то же имя класса для ВСЕХ Ваших контейнеров, как имеющихся, так и динамически появившихся?
Нет, ничего не мешает, это вообще не имеет значения.
>Мей би, Вы хотите иметь на странице всего ДВЕ кнопки Развернуть/Свернуть, а контейнеров у Вас будет десяток - при этом эти контейнеры у Вас будут появляться не по одному (взамен предыдущего) на странице, а сразу по пять (и все пять надо будет развертывать/свертывать одним нажатием одной кнопки)?
Кнопки Развернуть/Свернуть не нужны на экране, эти функции должны выполняться системно, а их работа направлена только на один контейнер, переданный в функцию параметром id.
Прикрепил примерный механизм работы. Вместо Развернуть/Свернуть выскакивает алерт описывающий произошедшее. На то, что функции ajax`а не очень корректно представлены(в двойном экземпляре) не обращайте внимания, не хотелось отлаживать ради представления одной функцией. | |
|
|
|
|
 1.6 Кб |
|
|
для: Рома
(22.05.2010 в 17:49)
| | Вот попробовал сам сваять, но не понятно откуда появляется третий цикл, и вместо того, чтобы свернуться/развернуться, блок сворачивается затем разворачивается, затем снова сворачивается. И наоборот. | |
|
|
|
|
|
|
|
для: Рома
(23.05.2010 в 00:13)
| | Я извращаюсь, прописываю Вам пункты с объяснением механизма работы спойлера, а Вы по-прежнему гоните одну и ту же "пургу" с display = 'none', display = 'block' и совершенно неизвестным this.
[поправлено модератором] | |
|
|
|
|
|
|
|
для: АЯ
(24.05.2010 в 09:51)
| | Спрошу у кого нибудь другого, извините что вообще побеспокоил. | |
|
|
|