Печатная версия с Javascript

7 April, 2007

XHTML/CSS

Я всегда знал два подхода к печатным версиям: старого типа – ставим ссылку “печатная версия”, пользователь переходит на новую страницу и видит печатную версию этой же страницы, и новый: добавляем css media=”print”, и только знающие люди могут нажать Print Preview или догадаться распечатать эту страницу. Вот и пришла маленькая идея комбинации лучших сторон этих двух подходов.

Что я хочу

А хочу я, что бы по клику на ссылку “печатная версия” какой то волшебник заменял media=”print” на media=”screen”, и страница преображалась без перезагрузки в печатный вид. Таким образом и пользователь экономит время(хоть и мизерное), и видит сам печатный вид без лазания по меню броузера. Вроде как – все довольны.

HTML

Для примера понадобится страница с печатной версией, это будет что то вроде этой. В head файла добавим print.css два раза для разных медиа:

  1. <!–Для собственно принтеров –>
  2. <link rel="stylesheet" type="text/css" media="print" href="css/print.css" />
  3. <!–Для нашего превью с джаваскриптом –>
  4. <link rel="alternate stylesheet" type="text/css" media="screen,projection" href="css/print.css" title="printview" disabled />

Атрибут disabled указан для того что бы в ИЕ эти стили корректно включались и отключались.(см. статью)

Теперь страничка полноценная – у нее есть печатная версия, и она нормально отображается в броузерах. Дело за магией.

Javascript

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

Потому я обратился к другой статье(спасибо CB за наводку), где описывается метод буквального отключения CSS Disabling
По сути взял с минимальными изменениями джаваскрипт оттуда, вот что я использовал для решения задачи:

function setPrintCSS(isPrint) {
// Определяем поддержку нужного нам элемента в броузерах
  if (document.getElementsByTagName)
      x = document.getElementsByTagName('link');
  else if (document.all)
      x = document.all.tags('link');
  else
  {
      alert('Простите, этот скрипт не работает в вашем броузере');
      return;
  }
// Пробегая по всем элементам LINK в HTML  - включаем и отключаем нужные нам стили
// идентифицируя их по атрибуту title
// параметр isPrint - отвечает просто за вариант стилей для печти или монитора
  for (var i=0;i<x.length;i++) {
      if(x[i].title == 'printview'){x[i].disabled = !isPrint;}
      if(x[i].title == 'screenview'){x[i].disabled = isPrint;}
  }
}

(немного более логичный нейминг по сравнению с первым вариантом, спасибо CB)
В результате в HTML можно добавить две ссылки вида:

  1. <a href="#" onclick="setPrintCSS(false)">Вернуться к стандартному виду</a>
  2. <a href="#print" onclick="setPrintCSS(true)">Печатная версия</a>

По клику на которые всё и будет происходить.
Вот простой пример этого приема.

Можно пойти дальше(спасибо Smash за идею), и позволить пользователям давать ссылку на печатную версию сайта. Для этого достаточно одной строки скрипта после задания нашей функции:

if(document.location.hash=='#print') setPrintCSS(true);

Смотреть пример с работающим #print.

Ссылки

Для красоты в media=screen я скрываю ссылку переключения в обычный вид, а в печатной версии соответствующую ссылку на печатную версию.

В конце

Вот такой маленький приемчик – иногда может быть довольно приятным, да и наконец позволяет более явно использовать нам наши CSS для принтеров. А то бывает пишешь-пишешь эти стили.. А они скопируют в ворд и распечатают по привычке =) Кстати многие любят читать печатные версии на сайтах, что бы ничего не мешало – а таким образом мы ускоряем им это переключение. Вдобавок, можно давать одинаковые тайтлы нескольким ЦСС файлам и они будут отключены все разом.
Буду рад услышать Ваши мысли, критику, приемы по этому поводу!

Обновлено: Спасибо Vladson за второй способ быстрой замены стилей, чуть менее абстрактный, но иногда возможно оптимальный. Задаем параметр id для элемента link(например main-css), и тогда

  1. <a href="#" onclick="document.getElementById(‘main-css’).href = ‘css/base.css’">Вернуться к стандартному виду</a>
  2. <a href="#" onclick="document.getElementById(‘main-css’).href = ‘css/print.css’">Печатная версия</a>

Оба споосба еще нуждаются в тестировании – но под виндой работают под всеми броузерами. А последний и под Konqueror.

XHTML/CSS

42 комментариев к “Печатная версия с Javascript”

memyself | 1. 7 April, 2007

Всё гениальное просто. Спасибо Вам большое!

Vladson | 2. 7 April, 2007

Только вот благодаря параметру “disabled” жертвуется “валидность”

Smash | 3. 7 April, 2007

Можно добавить href=”#print” и href=”#view”, и в зависимости от него включать или отключать нужные стили. Это добавит возможность сослатся на печатную версию.

Smash | 4. 7 April, 2007

Vladson, оберните его в СС или попробуйте disabled=”disabled”

Vladson | 5. 7 April, 2007

Я делал это по другому, просто добавил к первому link id=”main_css” и сделал ссылки

onclick=”document.getElementById(‘main_css’).href = ‘css/base.css'”
onclick=”document.getElementById(‘main_css’).href = ‘css/print.css'”

Кроссбраузерность вполне нормальная (проверял в IE-5-6-7, мозила-1-2, опера-7-8-9, Konqueror) и валидность не храмает…

Советую глянь на http://www.exclipy.com/ там тоже самое но ещё более грамотно…

Mourner | 6. 7 April, 2007

Хорошо написанная, полезная статья, молодец! Великолепно!

Только один момент, который можно улучшить – я (и не только) твёрдо убеждён, что в HTML-маркапе не должно быть вещей, которые не имеют смысла без работающего JS. Поэтому ссылки на печатную версию/обратно нужно генерить и вставлять в DOM динамически вместо того, чтобы прописывать в маркапе (тем более через атрибут onclick).

pepelsbey | 7. 7 April, 2007

Отличная статья. Даже не верится, что по-русски ;)

Amigo | 8. 8 April, 2007

спасибо, интересный ход!
главное, в лисе работает :)

tommy | 9. 8 April, 2007

Пример супер, да и сайт тоже. Очень много нового узнал, спасибо

Amigo, как по мне так в лисе практически все работает, что нельзя сказать об ие :)

akella | 10. 8 April, 2007

Спасибо всем!
@Vladson, да ты прав – можно и таким способом, спасибо. Но он, ИМХО, какой то чуть менее логичный, то есть мы подменяем а не переключаем. А насчет того линка так там используется как раз Style Switcher который как по мне слишком избыточен для таких задач, ну зачем мне запоминать в куку что он переключился на печатную версию? ) А валидность да.. есть такое, но когда я вставляю этот параметр только ради ИЕ – моя совесть чиста(почти) =), да и CC можно…

@Smash: спасибо да идею! Действительно иметь ссылку было бы еще удобней!

Главное нам теперь не написать мегафреймворк для работы с печатной версией :) Я уже вижу… Printr.js

Vladson | 11. 8 April, 2007

>>> какой то чуть менее логичный
Я так не считаю, мне кажется что очень даже ничего…
Единственное что выполнен он “топорно” (просто чтоб передать смысл) но это решается…

akella | 12. 8 April, 2007

да, смысл понятен, наверно ППК защищался от каких старожилов-броузеров, где то наверно этот параметр протектед.
А не нравится мне в этом методе то что в джаваскрипте учавствует важный контент – адрес ЦСС файла, не хотел бы я вмешивать..Никаких конкретных проблем – просто интуитивно так. В любом другом случае – бесспорно проще. Спасибо большое!

Zigzag | 13. 8 April, 2007

Юра, пасиб, действительно… гениально просто!

wmas | 14. 10 April, 2007

Вариантов всегда было много и в этом вся соль на раны или наоборот :) В любом случае – народу нравится, хотя вроде как можно просто display: none или скажем innerHTML нужного кусочка в всплывающем окне выводить :) Тоже варианты в копилку.

Vladson | 15. 10 April, 2007

>>> споосба еще нуждаются в тестировании
Не вижу смысла особо тестировать, дело в том что вроде все перечисленные способы достаточно кросс-браузерные…

Мой способ я проверял на винде IE, Firefox Opera, а также на Линуксе под Konqueror, Firefox и Epiphany (Epiphany тоже на Gecko)

akella | 16. 10 April, 2007

@ Vladson: Под дотестированием я имел ввиду МАК. И пусть доля его мала, но людям которые его имеют как правило лучше все видеть в хорошем свете :)
Ну и + в ИЕ всякое бывает…. Без disabled например все работает в ИЕ, но с маленьким глючком – принт стили включаются не с первого раза.

Sam | 17. 10 April, 2007

Довольно интересный способ.
И расписано хорошо.

Спасибо за статью.

ilya shvets | 18. 10 April, 2007

Что-то долго вы его делаете.

akella | 19. 11 April, 2007

Кого? =)

Misha | 20. 14 April, 2007

на css проще, как по мне. Но за статью все равно зачот, хороша, впрочем, как и все :)

Алексей | 21. 15 April, 2007

Изобрели велосипед?

Print to Preview -> http://alistapart.com/articles/printtopreview

akella | 22. 15 April, 2007

Вот спасибо за ссылку – а я пропустил, буду теперь и этот вариант знать ). Но у меня как то попроще кажется..

Crash Override | 23. 19 April, 2007

Интересно. Надо прикрутить к блогу будет :)

JS | 24. 23 April, 2007

Здравствуйте!
К сожалению, не силен в скриптах. Подскажите, пожалуйста, как надо доработать этот скрипт, чтобы при включении версии для печати для нее выводилась спец. шапка (отличающаяся от основной страницы , например, логотип + текст), а после контента спец. footer, также отличающийся от основной стр. Насколько я понял, надо сделать проверку и, если версия для печати, то: document.write (‘текст’).?

akella | 25. 23 April, 2007

В обычном CSS файле скрывайте ваш печатный футер, а в печатном CSS файле скрывайте ваш обычный футер. Добавьте их сразу оба в код.

JS | 26. 23 April, 2007

Да, этот способ понятен, спасибо. А вот можно ли как раз без этого скрыть/показать? Именно поэтому и зарекся про document.write. Просто не хотелось бы в основном документе держать альтернативные header и footer. Или у этого способа есть какие-то сильные недостатки?

akella | 27. 23 April, 2007

Серьезные ровно настолько насколько важен альтернативный футер и хедер. Вдруг ЖС отключен, да и как то некошерно хранить в ЖС части контента.

Мне кажется оптимально держать по два варианта в коде, или пытаться их как то скомпромиссить – что бы хватало одного который в печатной версии бы становился таким каким надо.

Николай | 28. 13 May, 2007

Потрясающая статья. Спасибо.

Евгений | 29. 21 May, 2007

в общем-то статья на нужную тему, а про менталитет я говорить не буду, это же банально очень про менталитет-то говорить, мол это только в нашей стране никак догадаться не могут, что страницу можно отправить на печать нажав ctrl+p или аналогичными телодвижениями

ogonkov | 30. 31 May, 2007

а можно ещё сделать CSS, где ссылка “Вернуться к стандартному виду” будет скрываться

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

возможно где-то я накосячил в своих рассуждениях, это так, мысли вслух :)

VLad | 31. 24 June, 2007

Полаконичней, чем на Alistapart будет. Но ИМХО document.all в этом скрипте смысла использовать нет. Я склонен разделять мнение этого товарища – http://simonwillison.net/2003/Aug/11/documentAll/

А что касается диалога Акеллы с Владсоном, то извечный камень преткновения – логика или простота очень редко имеет золотую середину.

Vladson | 32. 25 June, 2007

>>> что касается диалога Акеллы с Владсоном
Что касается диалога то просто мы столкнулись с разными ситуациями, в одних случаях хорошо одно, в других другое.

Я рад что было употреблено слово “диалог” а не “спор” так как обе точки зрения правильны.

(Далее ИМХО:)
Вся прелесть вёрстки заключается в том, что изначально нет правильного и неправильного варианта. Есть множество разных способов, и что именно отличает “мастера” от “новичка” это то что он может выбрать тот или инной способ в зависимости от сложившейся ситуации….

(Как говорится в знаменитой поговорке “Что русскому хорошо, то немцу смерть” или как в юмористическом ремиксе “Что немцу кирпич, то русскому мигающий зелёный”)

VLad | 33. 1 July, 2007

>>> изначально нет правильного и неправильного варианта
Глубоко убежден, что есть. Не в приложении к теме обсуждения, а в принципе. И мастера от новичка как раз и отличает умение выбрать правильный вариант, более изящный вариант, более лаконичный вариант.
Конечно существуют равнозначные и равновозможные варианты, но там где “этого требует истина”:) я привык к категоричности. В качестве простого примера: табличная верстка – это неправильно вне зависимости от ситуации, кто бы что ни говорил по этому поводу. Часто желание написать попроще основывается на неправильном понимании простоты.

Flo | 34. 5 January, 2008

такой прием не валиден xhtml strict
можно как нибудь обойтись без disabled?

akella | 35. 5 January, 2008

Я не знаю зачем нужен именно стрикт, модно? Поставьте обычный html и используйте, либо пробуйте метод, ссылка на который дана в комментарии номер 21

Валидатор это инструмент кодера, ну вызывает это ошибку… ну и? Вы же о ней знаете, и знаете что она безвредна для всех.

Андрей - Практик | 36. 30 March, 2008

В 99% случаев страница с “версией для печати” должна иметь другой
html код, поэтому даже и мыслей нет заморачиваться с JS.
Если и использовать JS, то придётся перед этим сделать html версию и
только потом настраивать вторую JS версию. Когда выдаётся сообщение
“этот скрипт не работает в вашем броузере” – это непрофессионально!!!
Когда “функция отключается” при отсутствии JS – это тоже несерьёзно!

akella | 37. 30 March, 2008

На моих четырех сайтах, подходит тот же самый HTML. Так как я использую хорощий ХТМЛ, позволяющий сделать с ним все что мне нужно через ЦСС. Убедитесь в этом на этой самой странице. Вы видимо недостаточно хорошо знакомы с HTML+CSS.
Таким образом, должно существовать еще 396 сайтов для которых это не так :) Очень сомневаюсь.

Предусматривать доступность для пользователей без джаваскрипт безусловно нужно. Но и забывать о том что таких пользователей менее 1 процента, тоже не стоит. Я делал доклад в москве на Сlientside целиком посвященный доступности, видимо вам будет интересно http://cssing.org.ua/2007/11/11/client-side-2007/

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

Потому извините :) Ваш комментарий какой-то поверхностный и несерьезный. Жаль что вы не вдумались в суть поста.

sonika | 38. 5 October, 2008

Спасибо за способ, пристроила себе в блог!
Юрий, а не мог бы ты вывести форму поиска в блоге? Искать что-либо очень неудобно…

akella | 39. 5 October, 2008

Круто! =)
Я её спрятал в “архивах“. Мало кто искал по статистике =(

P.S.: наверное случайно получилось – сейчас у тебя ссылка на печатную версию выводится в листингах статей, а не только на single_post.

Морозов | 40. 27 October, 2008

Попробовал сделать по-вашему, но при обилии на странице флешевых банеров и разного рода динамики на javascript в момент переключения таблиц стилей IE просто вылетает (демонстрацию, к сожалению, привести не могу). При этом вариант с подменой href у основной таблицы стилей работает.

Документ для печати. Версия с Javascript « uspeshnyy.ru – Личный блог | 41. 2 November, 2010

[…] пойти дальше(спасибо Smash за идею), и позволить пользователям давать ссылку на […]

nadietax | 42. 3 August, 2012

Сайт nadietax.com – женский сайт о диетах, здоровом образе жизни, красоте, женском здоровье

Оставить комментарий