Спойлеры в блоге

SpoilerВы знаете, что такое спойлер (англ. spoiler)? Нет, не тот, который на щетке лобового стекла автомобиля и не антикрыло для него же :-) Сейчас я говорю об элементе дизайна, что используется для сокрытия информации, которую читатель может увидеть лишь намеренно нажав на кнопку. Подобное может быть полезно, если спрятанную под спойлером информацию не нужно видеть всем (например, содержание фильма, на который читатель только еще собирается пойти). Или же, если текст статьи перемежается большими кусками вспомогательного материала, который не каждому интересен (например, сравнительные таблицы, куски кода, примеры).

Сейчас мы добавим возможность создания спойлеров и в наш блог!

Итак, в создании спойлеров нам как всегда помогут javascript и CSS. Сначала интегрируем скрипт. Для этого открываем шаблон на редактирование (Дизайн->Изменить HTML), находим закрывающий тэг </body> и прямо перед ним добавляем следующий код:
<script type='text/javascript'>
  WidgetSpoilerManager.setOption("defaultTitleText", "Подробнее");
</script>
<script src='https://drive.google.com/uc?export=download&amp;id=0B3_dGXEjBVdPMWFiaHhoQnhPc1k' type='text/javascript'/>
Видите в коде слово "Подробнее"? Этим словом будет по умолчанию озаглавлен наш спойлер, если мы явно не зададим ему заголовок.

Теперь совместим полезное с... не менее полезным! Увидим спойлер в действии, а заодно, желающие смогут ознакомиться с содержимым скрипта, доступным по адресу https://drive.google.com/uc?export=download&id=0B3_dGXEjBVdPMWFiaHhoQnhPc1k, к которому выше шло обращение:

WidgetSpoilerManager = {
  options: {
    mainSectionId: "Blog1",
    spoilerClassName: "spoiler",
    hiddenClassName: "spoiler-hidden",
    visibleClassName: "spoiler-visible",
    controlClassName: "bar",
    textClassName: "text",
    copyClassName: "copy",
    defaultTitleText: "Подробнее"
  },
  setOption: function (option, value){
    if (this.options[option] != undefined){this.options[option] = value}
  },
  getElementsByClassName: function (classname, node){
    if(!node) node = document.getElementsByTagName("body")[0];
    var a = [];
    var re = new RegExp('\\b' + classname + '\\b');
    var els = node.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
      if(re.test(els[i].className))a.push(els[i]);
    return a;
  },
  toggle: function (elem){
    var parent = elem.parentNode;
    if (parent.className == this.options.hiddenClassName){
      parent.className = this.options.visibleClassName;
      return
    }
    parent.className = this.options.hiddenClassName;
  },
  init: function assignSpoilers(){
    var parentNode = document.getElementById(this.options.mainSectionId);
    var spoilers = this.getElementsByClassName(this.options.spoilerClassName, parentNode);
    for(var i=0,j=spoilers.length; i<j; i++){
      spoilers[i].className = "spoiler-hidden";
      var div1 = document.createElement("div");
      var div2 = document.createElement("div");
      div1.className = this.options.controlClassName;
      div1.innerHTML = spoilers[i].getAttribute("title") ? spoilers[i].getAttribute("title") : this.options.defaultTitleText;
      div1.onclick = function(){WidgetSpoilerManager.toggle(this)}
      spoilers[i].removeAttribute("title");
      div2.className = this.options.textClassName;
      div2.innerHTML = spoilers[i].innerHTML;
      spoilers[i].innerHTML = "";
      spoilers[i].appendChild(div1);
      spoilers[i].appendChild(div2);
    }
  }
}
WidgetSpoilerManager.init();

Добавим немного оформления для спойлера, чтобы он красиво выглядел. Для этого встроим необходимый CSS-код в шаблон под строку "/* Accents":
/* Accents
----------------------------------------------- */
.bar {
  background: #138FD8 url('https://lh5.googleusercontent.com/-SWOQVNt9y0M/TlT5KzL9cWI/AAAAAAAAAJw/TOt-RHHd4rg/spoiler-back.gif') no-repeat;
  border-radius: 3px;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  box-shadow: 1px 1px 1px #bbb;
  -webkit-box-shadow: 1px 1px 1px #bbb;
  -moz-box-shadow: 1px 1px 1px #bbb;
  padding-left: 30px;
  color: #fff;
  font-size: 15px;
  font-family: 'Trebuchet MS', Trebuchet, sans-serif;
  cursor: pointer;
}

.spoiler-hidden .bar {
  background-position: 0 0;
}

.spoiler, .spoiler-hidden .text {
  display: none;
}

.spoiler-visible .bar {
  background-position: 0 -20px;
  border-radius: 3px 3px 0 0;
  -webkit-border-radius: 3px 3px 0 0;
  -moz-border-radius: 3px 3px 0 0;
  box-shadow: 1px 0 1px #bbb;
  -webkit-box-shadow: 1px 0 1px #bbb;
  -moz-box-shadow: 1px 0 1px #bbb;
}

.spoiler-visible .text {
  display: visible;
  padding: 5px 1em 0;
  border: 1px solid #138FD8;
  border-top-width: 0;
  border-radius: 0 0 3px 3px;
  -webkit-border-radius: 0 0 3px 3px;
  -moz-border-radius: 0 0 3px 3px;
  box-shadow: 1px 1px 1px #bbb;
  -webkit-box-shadow: 1px 1px 1px #bbb;
  -moz-box-shadow: 1px 1px 1px #bbb;
}
С подгонкой цветовой гаммы, формы спойлера и шрифтов под свой блог, думаю, сложностей возникнуть не должно :-)

Теперь о самом главном: как же активировать сие чудо? Используем для этого простую конструкцию: <div class="spoiler" title="заголовок спойлера">спрятанный текст</div>.

Есть вопросы? Спрашивайте - буду рад помочь!

Комментариев: 45

  1. Да, это полезная штука. Я ее возьму на заметку. А есть ли возможность некоторые посты на Блогспоте вообще закрыть для общего доступа. Я приведу пример: я хочу сделать блог про сновидения и символы, но те посты, где я описываю свои сны, я хочу закрыть. Или скрыть в посте эту часть текста. Такое возможно?

    ОтветитьУдалить
    Ответы
    1. С помощью javascript видимость этого создать можно. Заходя на страницу читатель не будет видеть скрытую часть текста (кроме избранных), но если он просмотрит исходный код страницы, то увидит все.

      Полагаю, что можно попробовать "скрытую страницу" создать на другом ресурсе, поддерживающем доступ к странице по паролю, и добавить подобную стороннюю страницу в блог через тэг iframe. Если этот способ сработает, то надежность у него будет железобетонная.

      Есть третий вариант, самый простой: создать в блоге отдельную страницу (не статью, а свободную страницу) в которую писать подобные вещи. Эта страница не должна быть доступна ни с одной страницы блога и должна иметь защиту тэгами от индексирования. Плюс, все ссылки, идущие с нее тоже должны быть защищены от просчитывания поисковиком. Избранные же читатели должны получать ссылку на эту страницу непосредственно из Ваших рук.

      P.S. Занимаетесь толкованием снов? Не буду критиковать ваше безобидное увлечение. Но как человек, прошедший дальше - к осознаванию себя в сновидческом мире - скажу, что это путь в никуда :-/

      Удалить
  2. Тимофей, это слишком для меня сложно. Я тогда просто оставлю блог закрытым. Только для себя. В блоггере очень удобно попытаться понять их язык. В ярлыках указать основные элементы сна, чтобы потом можно было посмотреть все сны, где фигурировал этот элемент. Посмотреть даты и сопутствующие обстоятельства.
    Тимофей, то есть Вы думаете, что сны вообще бессмысленны?

    ОтветитьУдалить
    Ответы
    1. Ну, почему же сны бессмысленны. Сны - это отражение наших переживаний в объективной реальности. Толковать сны можно. Дедушка Фрейд это доказал. Единственное, чтобы грамотно их толковать, нужно быть весьма неплохим психологом и достаточно много знать о субъекте. А толкования типа "приснилась жаба - к засухе", это все ерунда.

      Но, если вы хотите пойти дальше банальной психологии, то попробуйте почитать роман Андрея Реутова "Хакеры сновидений". Он есть в сети. Тогда Вы, возможно, поймете мой скепсис.

      P.S. Думаю, в комментариях к статье "Спойлеры в блоге" тему снов и сновидений развивать все же не стоит. Если что, пишите в личку.

      Удалить
  3. Спасибо! Иногда бывает нужно...

    ОтветитьУдалить
    Ответы
    1. И не говорите. Я, например, пользуюсь возможностями этого виджета с завидной периодичностью...

      Удалить
  4. На blogspot не принимает форма такие теги - пишет недопустимый тег div!
    Тег img принял - картинки размещаются. А вот со спойлером не дает.

    ОтветитьУдалить
  5. Речь идет о форме комментариев. Я разместил Ваши коды для картинок и для выделения цитаты - они работают. А вот чтобы скрыть под спойлер - не принимает окно ввода комментариев код спрятанный текст написал на русском - а то не будет видно наверное здесь спрячется :)

    ОтветитьУдалить
    Ответы
    1. Скажите, я ХОТЬ ГДЕ-НИБУДЬ в статье упомянул, что этот виджет будет работать в комментариях? С картинками и цитатами я четко это прописывал. Этот виджет создан для оформления статей, а не комментариев!

      Удалить
    2. Да действительно! Туплю однако!

      Удалить
  6. .comment-form {
    max-width: 100% !important;
    }
    Этот код тоже ничего не меняет. Окно комментария остается таким же.

    ОтветитьУдалить
    Ответы
    1. Статья, из которой Вы почерпнули этот код, писалась для линейной структуры комментариев, когда иерархической еще попросту не существовало. У Вас же сейчас как раз иерархическая.

      И, пожалуйста, впредь обсуждайте материал какой-либо статьи в топике этой самой статьи, а не там, где Вам оказалось проще оставить комментарий!

      Удалить
    2. Спасибо за ответ. Совет принят. :)

      Удалить
  7. Здраствуйте ,Тимофей , у меня вопрос ,может не совсем по существу .Возможно ли сделать допустим несколько спойлеров в один блог с разным оформлением (цветом к примеру)?Я так понимаю ,что надо прописать каждому спойлеру свой стиль .КАк это сделать .если возможно.Только я чайник и практически не разбираюсь в кодах !
    Спаибо !

    ОтветитьУдалить
    Ответы
    1. Да, подобное возможно. Нужно будет в скрипте переименовать все классы, которые задействованы в CSS-оформлении и разработать новое оформление уже на ссылаясь на эти имена. Разумеется, нужно не забыть подключить видоизмененый скрипт в шаблоне.

      Но уж Вы извините, обучать Вас CSS с нуля в мои планы не входит. Откройте справочник по CSS (их полно в сети) и постарайтесь понять, что обозначают те CSS-параметры, что я использую. Так и научитесь чему-то!..

      Удалить
  8. Хочу восстановить справедливость!!!!
    ====Админ пишет...
    1 апреля 2012 г., 23:47
    .comment-form {
    max-width: 100% !important;
    }
    Этот код тоже ничего не меняет. Окно комментария остается таким же.======

    Только что вставила этот код в свой блог,где комментарии иерархи( тьфу, язык сломать можно) резьбовые - отлично код работает....
    С уважением к автору блога....

    ОтветитьУдалить
  9. Я не как не могу в коде найти строку Accents. Искал через поиск результатов нет. Такое может быть?
    Спасибо!

    ОтветитьУдалить
    Ответы
    1. Такое может быть. Просто сделайте так, чтобы этот код был помещен НАД строкой "]]>".

      Удалить
  10. Здравствуйте ! У вас адрес скрипта похоже слетел .Либо файл удалился

    ОтветитьУдалить
    Ответы
    1. По неизвестной причине меня лишили моего аккаунта Google Code. Придется переместиться на другой сервис. Следите за изменениями ссылок на скрипты в статьях.

      Удалить
  11. Здравствуйте! Можете опубликовать содержимое скрипта чтобы я мог закинуть его на googlecode. Спасибо

    ОтветитьУдалить
    Ответы
    1. Как не забавно это звучит, но содержимое скрипта в статье есть. Просто оно под спойлером! Которые сейчас временно в моем блоге не работают...

      Просто откройте просмотр исходного кода страницы и скопируйте код оттуда. Или подождите где-то с недельку, когда я все починю.

      Удалить
  12. Тимофей, здравствуйте!
    [q]Видите в коде слово "Подробнее"? Этим словом будет по умолчанию озаглавлен наш спойлер, если мы явно не зададим ему заголовок.[/q]

    Что значит "явно задать заголовок"? Тут же, в первом коде? Или при помощи "title"?
    Спасибо.

    ОтветитьУдалить
  13. [Вдогонку] Прошу прощения. Разобрался. Таки да, с помощью "title". :-)

    ОтветитьУдалить
  14. А у меня плюсик не виден на полоске спойлера, кто знает почему такое может происходить?

    ОтветитьУдалить
    Ответы
    1. Плюсик - это картинка. Если он не виден, то скорее всего ссылка на картинку дана некорректно.

      Удалить
  15. А как сделать чтоб не во всю ширину был, а начинался с левой стороны спойлер и (например) на половину страницы или 200 пикселей к примеру шириной был, такое можно провернуть?

    ОтветитьУдалить
    Ответы
    1. Можно разумеется. Нужно внести кое-какие правки в сам скрипт спойлера.

      Удалить
    2. Ширину спойлера можно указать в самом div'е исползуя style="width:200px" или style="width:50%"

      P.S. Автору огромное спасибо за статью!!!
      P.S.S. Sunctorus, не нашел в Вашем коде (подключение скрипта), 4-ая строка, закрывающего тэга

      Удалить
    3. [q]Sunctorus, не нашел в Вашем коде (подключение скрипта), 4-ая строка, закрывающего тэга[/q]
      Слэш перед закрывающей скобкой тэга заменяет полноценный закрывающий тэг.

      Удалить
  16. Всё работает замечательно, но есть одна тонкость. В livejournal.com, если ты перешёл непосредственно в топик (ссылка изменилась на прямую на этот топик), то спойлер как бы исчезает, и топик сразу показывается весь. Удобно тем, что при перезагрузке страницы ничего не закрывается, и топик виден весь сразу. Можно такое сделать и в блоггере?

    ОтветитьУдалить
    Ответы
    1. А как выглядит НЕПРЯМАЯ ссылка на топик в блоггере, можно поинтересоваться? А то я что-то не очень понимаю, что Вы хотите.

      Удалить
    2. http://kubinkaman.blogspot.com/ - ссылка на блог
      http://kubinkaman.blogspot.com/2014/11/blog-post_69.html - прямая ссылка на топик блога

      Нужен вариант спойлера, который работает как тег "lj-cut" в LiveJournal, то есть по второй ссылке спойлер был открыт по умолчанию (или вообще исчезал, оставляя содержимое - так в LiveJournal).

      Удалить
    3. А чем Вас не устраивает блоггеровский тэг <!--more-->?

      Удалить
    4. Он опять же не так работает - сразу переходит по ссылке внутрь конкретного топика :). А хочется именно как в жж - чтобы спойлер "раскрывался" по клику, но ты остаёшься на главной странице блога. А при переходе по прямой ссылке в топик, нажав на его заголовок, спойлер сразу раскрыт. Я так понимаю, надо в скрипте отслеживать какая именно страница блога загружена, главная или страница конкретного топика, и в последнем случае - просто показывать содержимое спойлера без обрамления и кнопок.

      Удалить
    5. Я не очень понимаю высший смысл подобного. Да, честно говоря, и сам механизм от меня ускользает...

      Удалить
    6. Снова вернулся к этому. Имхо, надо указать народу, что widget_spoiler.js лучше выложить самому и юзать по своей ссылке. Что касается прошлого разговора, то смысл в том, что при прямом переходе по адресу поста - спойлеры все открыты сразу, это удобно.

      Удалить
  17. А усли нет вот этого /* Accents?????????????????????Что делать??????????????

    ОтветитьУдалить
    Ответы
    1. Вика, главное, чтобы вносимый код был до строки: [q]]]>[/q]

      Удалить
    2. А если и этого нет "]]>"!!!!!!!!!!!!!!???????????????????7

      Удалить
    3. Значит Ваш блог не на платформе Blogger или Вы используете какой-то сторонний шаблон.

      Удалить
  18. Ответы
    1. Не понял, какой тэг вы не можете найти. Скорее всего его "съел" модуль комментариев.
      Напишите его русскими буквами.

      Удалить

Хотите подписать свой комментарий, но у вас нет аккаунта? Выберите в выпадающем списке Имя/URL.
Вы сможете вписать свои имя или ник. Поле для указания URL можно оставить пустым.

Тэги, допустимые в комментариях