спойлер

Тема в разделе "PHP", создана пользователем Sachek, 13 окт 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. Sachek

    Sachek Умелый

    Регистр.:
    23 мар 2009
    Сообщения:
    387
    Симпатии:
    102
    Помогите пожалуйста написать "Спойлер" для сайта.
    Думаю понятны требования:
    Скрытие и открытие текста.
    Желательно, что бы подгружалось не со сторонней страницы, а именно с той, которую загрузили...
    Ярким примером может быть любой торрент. Там есть возможность скрыть текст под спойлер.
    Скрипт желательно на php, но можно и java скрипты.
    Заранее спасибо.:)
     
  2. Виллен

    Виллен

    Регистр.:
    12 мар 2009
    Сообщения:
    235
    Симпатии:
    60
    java script нужен по любому.
    Именно он определяет логику скрытия/показа спойлера.

    Что значит "Желательно, что бы подгружалось не со сторонней страницы"?
    Текст спойлера и так уже загружен, но имеет атрибут "скрытый".
    Посмотри на большинстве форумах спойлеры, и глянь в исходный код страницы. Текст спойлера обычно уже присутствует.
    Не прогруженны только картинки, умные браузеры не грузят их пока они невидны.

    Если это не подходит и нужно прятать в спойлерах мегабайтные куски текста, которые не грузятся пока спойлер не открыть, то тут без аякса не обойтись. Интеграция в существующий форум будет сложной.


    ---------------------
    спойлер:
    понадобится
    1. jquery. У меня jquery-1.1.1.pack.js лежит в папке js
    2. иконки + и -
    3. css
    Код:
    html, body {
     margin: 20px;
     color: #000;
     background: #FFF url(fon2.gif);
     font-family: Arial, Helvetica, sans-serif;
     font-size: 16px;
     line-height: 20px;/*  16?1.125=18 */
     text-align: left; 	
    }
    
    /*---spoiler--------------------------------------------------------------------------------------------------------------*/
    .spoiler_wrap {
     width: 85%;
     border-top:1px solid  #5E1E07;
     border-left:1px solid  #5E1E07;
     border-right:1px solid  #9F5F48;
     border-bottom:1px solid  #9F5F48;
    
    }
    
    .spoiler_head {
     font-size: 11px; padding: 1px 14px 3px; margin-left: 6px; line-height: 15px;
    }
    
    div.spoiler_body {
     display: none;
    }
    
    
    div.spoiler_body, div.quote_body {
     margin:0px;
     padding:5px; 
     border-top:1px solid  #5E1E07;
    /* border-left:1px solid  #5E1E07;
     border-right:1px solid  #9F5F48;
     border-bottom:1px solid  #9F5F48;*/
     overflow:auto;
    }
    
    .clear     { clear: both; height: 0; font-size: 0px; line-height: 0px; overflow: hidden; }
    .clickable { cursor: pointer; }
    .folded    { background: transparent url(icon_plus.gif) no-repeat left center; padding-left: 14px; }
    .unfolded  { background: transparent url(icon_minus.gif) no-repeat left center; padding-left: 14px; }
    /*---spoiler--------------------------------------------------------------------------------------------------------------*/
    
    4. js скрипты и css в заголовке
    Код:
    <link rel="stylesheet" href="style.css" type="text/css">
    <script language="javascript" type="text/javascript" src="js/jquery-1.1.1.pack.js"></script>
    <script type="text/javascript">
    $(document).ready(
    function(){
      $('div.spoiler_head')
      .click(function() {
        $(this).toggleClass('unfolded');
        $(this).next('div.spoiler_body').slideToggle('fast');
      });
    });
    </script>
    
    5. php функция
    PHP:
    function format_comment($s) {

        
    $s htmlspecialchars($s);

        
    $str_search[] = "[br]";
        
    $str_repl[] = "<br>";
        
    $str_search[] = "[spoiler]";
        
    $str_repl[] = "<div class=\"spoiler_wrap\"><div class=\"spoiler_head folded clickable\">Скрытый текст</div><div class=\"spoiler_body\">";
        
    $str_search[] = "[/spoiler]";
        
    $str_repl[] = "</div></div>";
        

        
    $preg_search[] = '/\[spoiler=(.+?)\]/i';
        
    $preg_repl[] = "<div class=\"spoiler_wrap\"><div class=\"spoiler_head folded clickable\">Скрытый текст</div><div class=\"spoiler_body\">";

        
    $s str_replace($str_search$str_repl$s);
        
    $s preg_replace($preg_search$preg_repl$s);

        if (
    function_exists('tidy_repair_string'))
            {
            
    $tidy_cfg = array(
                        
    'drop-empty-paras'  => false,
                        
    'fix-uri'           => false,
                        
    'force-output'      => true,
                        
    'hide-comments'     => true,
                        
    'join-classes'      => false,
                        
    'join-styles'       => false,
                        
    'merge-divs'        => false,
        
    #                'merge-spans'       => false,      // нужно будет включить после обновления версии tidy
                        
    'newline'           => 'LF',
                        
    'output-xhtml'      => true,
        
    //                'preserve-entities' => true,
                        
    'quiet'             => true,
                        
    'quote-ampersand'   => false,
                        
    'show-body-only'    => true,
                        
    'show-errors'       => false,
                        
    'show-warnings'     => false,
                        
    'wrap'              => 0,
                    );        
            
    $s tidy_repair_string($s$tidy_cfg'raw');
            }
        return 
    $s;
    }
    рекомендуется установить модуль tidy (функция tidy_repair_string), но он не обязателен.
    незакрытые теги можно потом поправить вручную.
    С настройками tidy не разбирался, выдрал из готового проекта. Работает! незакрытые дивы закрывает

    6. Использование
    PHP:
    $str '[spoiler]Спойлер 1[/spoiler][br]
    [spoiler]Спойлер 2[spoiler]вложение[/spoiler][/spoiler][br]
    [spoiler]Спойлер 3[spoiler]вложение 1[spoiler]вложение 2[/spoiler][/spoiler][/spoiler][br][br]

    [spoiler="qqq"]Спойлер 4[/spoiler][br]
    [spoiler=qqq.tt]Спойлер 4[/spoi ler][br]
    [spoiler=qqq"]Спойлер 4[/spoiler][br]
    <a href=></a>

    [spoiler][spoiler]
    '
    ;
         
         
    $str format_comment($str);
         
         echo 
    $str;
    В тестовой строке полно вложенных спойлеров и намеренных ошибок.




    7. Результат
    http://80.92.99.122/test/testspoiler.php
     
    Disher нравится это.
  3. alexz15

    alexz15

    Регистр.:
    3 окт 2008
    Сообщения:
    394
    Симпатии:
    191
    HTML:
    <script type="text/javascript">
    function p() {
    	if (document.getElementById('p').style.display == 'none') {
    		document.getElementById('p').style.display = 'block';
    	} else {
    		document.getElementById('p').style.display = 'none';
    	}
    }
    </script>
    
    <a href="#" onclick='p()'>показать\скрыть</a><br/>
    
    <div id="p" style="display:none;background-color:#F2F2F2;">
    Скрытый текст
    </div>
     
  4. Alternator

    Alternator

    Регистр.:
    23 мар 2009
    Сообщения:
    295
    Симпатии:
    145
    короче, и более многовариантно:
    HTML:
    
    <script type="text/javascript">
    function p(elem)
    {
    while(elem.tagName!='DIV')
    	elem=elem.nextSibling;
    elem.style.display=elem.style.display=='none'?'':'none';
    }
    </script>
    <a href="#" onclick='p(this);return false;'>показать\скрыть</a><br/>
    <div style="display:none;background-color:#F2F2F2;">
    Скрытый текст
    </div>
    
    скрывает/показывает следующий тег DIV после ссылки
    также не добавляет # в конец адресной строки
     
  5. Виллен

    Виллен

    Регистр.:
    12 мар 2009
    Сообщения:
    235
    Симпатии:
    60
    alexz15, Alternator:
    здесь раздел php. ТС тоже про php спрашивал
    показали бы лучше как оптимальнее парсить теги

    Решение 1. конструкция:
    PHP:
        $s preg_replace("/\[spoiler\](.+?)\[\/spoiler\]/i",
        
    "<div class=\"spoiler_wrap\"><div class=\"spoiler_head folded clickable\">Скрытый текст</div><div class=\"spoiler_body\">\\1</div></div>"$s);
    не понимает вложенность.

    Решение 2. она же в цикле
    в конечном - вложенность ограничена
    в бесконечном - возможно зацикливание


    Решение 3. как в моем примере выше. встречается в phpbb
    потенциально опасна не закрытыми тегами,
    решается применением tidy либо ручной проверкой валидности html.

    Что еще ?
     
Статус темы:
Закрыта.