Для Internet Explorer впервые реализовали события beforeprint и afterprint, и долгое время он был единственным, кто их поддерживает. Затем подтянулась Mozilla, поддерживающая эти события с 6-ой версии своего браузера. Вебкит очень долго не решался на реализацию, и наконец полностью от неё отказался, отсылая нас к интерфейсу matchMedia. Опера, насколько автор смог разобраться, не реализовала ни события, ни matchMedia, хотя не исключено недостаточное гугление этого вопроса.
На основании всего вышеизложенного хочется поделиться с читателями простым плагином jQuery, который добавляет поддержку методов beforeprint и afterprint.
Предположим, у вас на сайте есть страница, которую пользователи будут печатать. Для примера рассмотрим карты Гугла (патриотично было бы рассмотреть карты Яндекса, но они реализовали печать только на отдельной странице по клику на спец-кнопку). Если вы решите её распечатать в Google Chrome, то увидите примерно следующий результат:
Гугл поступил просто и красиво. С помощью css media print убрал все лишние элементы, стилизовал под печать оставшиеся, и честно написал справа вверху: “такой способ может привести к некорректному результату, так что лучше воспользоваться ссылкой печать”.
Что гугл упустил? Он неверно центрирует карту на печати в хроме. В оригинале она у автора центрирована по Москве, здесь же смещена. Причем чем больше ширина экрана, тем сильнее смещение. Это происходит из-за того, что в Google Maps не запускают простой джаваскрипт для обновления карты в print media.
Теперь починим баг с помощью вышеприведенного плагина:
Профит!
Теперь мы можем настраивать внешний вид страницы для печати не только с помощью CSS, но и с помощью JavaScript. Проверено в ИЕ8+, Хроме и Мозилле.
Если у вас jQuery древнее 1.7 замените в коде плагина метод on() на bind(), теперь плагин должен поддерживаться для версий 1.4.3+.
На основании всего вышеизложенного хочется поделиться с читателями простым плагином jQuery, который добавляет поддержку методов beforeprint и afterprint.
/**
* @author Alexander Burtsev
* @description Almost cross browser handling for events afterprint and beforeprint
* @requires jQuery 1.7+
*/
$.fn.beforeprint = function(callback) {
return $(this).each(function() {
if ( !jQuery.isWindow(this) )
return;
if ( this.onbeforeprint !== undefined )
$(this).on('beforeprint', callback);
else if ( this.matchMedia )
this.matchMedia('print').addListener(callback);
});
};
$.fn.afterprint = function(callback) {
return $(this).each(function() {
if ( !jQuery.isWindow(this) )
return;
if ( this.onafterprint !== undefined )
$(this).on('afterprint', callback);
else if ( this.matchMedia )
this.matchMedia('media').addListener(callback);
});
};
Об использовании
Предположим, у вас на сайте есть страница, которую пользователи будут печатать. Для примера рассмотрим карты Гугла (патриотично было бы рассмотреть карты Яндекса, но они реализовали печать только на отдельной странице по клику на спец-кнопку). Если вы решите её распечатать в Google Chrome, то увидите примерно следующий результат:
Гугл поступил просто и красиво. С помощью css media print убрал все лишние элементы, стилизовал под печать оставшиеся, и честно написал справа вверху: “такой способ может привести к некорректному результату, так что лучше воспользоваться ссылкой печать”.
Что гугл упустил? Он неверно центрирует карту на печати в хроме. В оригинале она у автора центрирована по Москве, здесь же смещена. Причем чем больше ширина экрана, тем сильнее смещение. Это происходит из-за того, что в Google Maps не запускают простой джаваскрипт для обновления карты в print media.
Теперь починим баг с помощью вышеприведенного плагина:
// My use case
(function() {
var _links = $('link[media="print"]');
$(window)
.beforeprint(function() {
_links.attr('media', 'all');
map.updateAfterLayoutChange();
})
.afterprint(function() {
_links.attr('media', 'print');
map.updateAfterLayoutChange();
});
// Метод updateAfterLayoutChange() выдуманный, да и ссылка map тоже
})();
Профит!
Итого
Теперь мы можем настраивать внешний вид страницы для печати не только с помощью CSS, но и с помощью JavaScript. Проверено в ИЕ8+, Хроме и Мозилле.
Если у вас jQuery древнее 1.7 замените в коде плагина метод on() на bind(), теперь плагин должен поддерживаться для версий 1.4.3+.