Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

HTML+CSS+JavaScript

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Не могу доделать функцию спойлера, не знаю всего синтаксиса javascript
 
 автор: Рома   (19.05.2010 в 15:11)   письмо автору
 
 

Сделал примерный алгоритм функции спойлера открывающей блок, но запустить не могу.
Хочу узнать правильный ли вообще алгоритм, если да то как его довести до работоспособности, а если нет, то что я не учел и в каком направлении двигаться.
Спасибо.

<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:11)
 

Обсуждение - http://www.softtime.ru/forum/read.php?id_forum=4&id_theme=70982
и результат - http://www.my-page29.narod.ru/

  Ответить  
 
 автор: Рома   (19.05.2010 в 15:51)   письмо автору
 
   для: АЯ   (19.05.2010 в 15:44)
 

Спасибо за ссылки

  Ответить  
 
 автор: Рома   (21.05.2010 в 14:31)   письмо автору
 
   для: АЯ   (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 в 16:37)   письмо автору
 
   для: Рома   (21.05.2010 в 14:31)
 

У Вас не определена переменная this ни в одной из функций.

Что такое this, и чему равно this.st - никто не знает.
Браузер - тоже не знает.

  Ответить  
 
 автор: Рома   (21.05.2010 в 17:55)   письмо автору
 
   для: АЯ   (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 в 20:45)   письмо автору
 
   для: АЯ   (21.05.2010 в 16:37)
 

Вобще на яве можно все что угодно сделать или нет?

А то свернув блок и подставив в него новый текст, с новым текстом блок разворачивается на туже высоту, что и со старым текстом, независимо от того меньше там текста или больше. И не так обидно, что механизм мне пока не дается, как то, что высота никак не хочет изменяться, а это важнее всего, иначе нет смысла и спойлером заниматься.

  Ответить  
 
 автор: АЯ   (21.05.2010 в 22:52)   письмо автору
 
   для: Рома   (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-коде один под другим.

  Ответить  
 
 автор: Рома   (22.05.2010 в 01:05)   письмо автору
 
   для: АЯ   (21.05.2010 в 22:52)
 

Даже не знаю что и ответить)))
Давайте я заработаю денег, тогда и обращусь к вам - и мне будет не стыдно сказать, что немножко не так, и у вас будет интерес, хорошо? А то кроме вас я не знаю ни кого, кто пишет js не прибегая к jquery.

А по поводу кода, объясню почему мне это не подходит: я готов содержать любую необходимую информацию о спойлере хоть даже в переменной сессии, только чтобы функции спойлера были отвязаны от id обрабатываемого блока. По другому мое приложение не заработает, т.к. я никогда не знаю какой id будет открываться/сворачиваться в следующий раз и какое в нем будет содержимое - все id уникальные и генерируются динамически по мере добавления/изменения информации. А разбив функцию спойлера на show и hide я обрежу пользователю возможность самостоятельно управлять контентом - в моем случае спойлер должен быть не удобством, а интерфейсом представления данных.

  Ответить  
 
 автор: АЯ   (22.05.2010 в 13:03)   письмо автору
 
   для: Рома   (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="myIdclass="myStandartClass">Содержимое</DIV>
<SPAN onclick="funcShow ('myID')">Развернуть</SPAN>
<SPAN onclick="funcHide ('myID')">Свернуть</SPAN>
и, соответственно, для любых ДРУГИХ "связок" "кнопка+кнопка+контейнер" иметь следующую структуру:
<DIV id="myIdOther1357class="myStandartClass">ДРУГОЕ содержимое</DIV>
<SPAN onclick="funcShow ('myIdOther1357')">Развернуть</SPAN>
<SPAN onclick="funcHide ('myIdOther1357')">Свернуть</SPAN>


IV. Если на выделенный жирно вопрос в п.III отвечаете положительно, то проблема Ваша решается элементарно. И я Вам помогу сразу.
Если я чего-то недопонял, то напишите - что именно Вам надо.

Мей би, Вы хотите иметь на странице всего ДВЕ кнопки Развернуть/Свернуть, а контейнеров у Вас будет десяток - при этом эти контейнеры у Вас будут появляться не по одному (взамен предыдущего) на странице, а сразу по пять (и все пять надо будет развертывать/свертывать одним нажатием одной кнопки)?

  Ответить  
 
 автор: Рома   (22.05.2010 в 17:49)   письмо автору
1.4 Кб
 
   для: АЯ   (22.05.2010 в 13:03)
 

>Вам ничего не помешает прописать одно и то же имя класса для ВСЕХ Ваших контейнеров, как имеющихся, так и динамически появившихся?

Нет, ничего не мешает, это вообще не имеет значения.

>Мей би, Вы хотите иметь на странице всего ДВЕ кнопки Развернуть/Свернуть, а контейнеров у Вас будет десяток - при этом эти контейнеры у Вас будут появляться не по одному (взамен предыдущего) на странице, а сразу по пять (и все пять надо будет развертывать/свертывать одним нажатием одной кнопки)?

Кнопки Развернуть/Свернуть не нужны на экране, эти функции должны выполняться системно, а их работа направлена только на один контейнер, переданный в функцию параметром id.

Прикрепил примерный механизм работы. Вместо Развернуть/Свернуть выскакивает алерт описывающий произошедшее. На то, что функции ajax`а не очень корректно представлены(в двойном экземпляре) не обращайте внимания, не хотелось отлаживать ради представления одной функцией.

  Ответить  
 
 автор: Рома   (23.05.2010 в 00:13)   письмо автору
1.6 Кб
 
   для: Рома   (22.05.2010 в 17:49)
 

Вот попробовал сам сваять, но не понятно откуда появляется третий цикл, и вместо того, чтобы свернуться/развернуться, блок сворачивается затем разворачивается, затем снова сворачивается. И наоборот.

  Ответить  
 
 автор: АЯ   (24.05.2010 в 09:51)   письмо автору
 
   для: Рома   (23.05.2010 в 00:13)
 

Я извращаюсь, прописываю Вам пункты с объяснением механизма работы спойлера, а Вы по-прежнему гоните одну и ту же "пургу" с display = 'none', display = 'block' и совершенно неизвестным this.

[поправлено модератором]

  Ответить  
 
 автор: Рома   (24.05.2010 в 23:22)   письмо автору
 
   для: АЯ   (24.05.2010 в 09:51)
 

Спрошу у кого нибудь другого, извините что вообще побеспокоил.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования