12 января 2011 г.

Печать защищенных PDF файлов

Не совсем про веб-разработку, но всё же...

Скачал себе как-то 65 книг по покеру. Решил распечатать несколько страниц из одной книги. Но оказалось что PDF файл (впрочем как и остальные 64) были защищены от печати.

После не очень продолжительных поисков нашел замечательную программу для снятия защиты — A-PDF Restrictions Remover. Программа платная, но к счастью есть 15-ти дневный trial.

7 января 2011 г.

Кроссбраузерный DOMContentLoaded

Многие из вас наверняка знают про событие DOMContentLoaded. Вкратце — это событие позволяет запускать выполнение кода сразу после того, как будет готово DOM-дерево. Это отличная альтернатива событию onload, которое срабатывает только после того, как будет загружен весь документ, включая все внешние файлы и изображения. О преимуществах DOMContentLoaded более детально говорить, я думаю, не стоит. Но к сожалению свободно пользоваться DOMContentLoaded на данный момент нельзя, в виду того, что не все браузеры это событие поддерживают. А не поддерживают это событие вот какие браузеры:

  • Internet Explorer до 9-ой версии
  • Opera до 9-ой версии
  • Gecko-based браузеры с версией движка ниже 1.8
    • Firefox ниже версии 1.5
  • Webkit-based браузеры с версией движка ниже 525.13
    • Safari ниже версии 3.1

Данные о поддержке браузерами события DOMContentLoaded взяты из скрипта contentloaded.js достопочтенного Diego Perini.

Делее мы рассмотрим методы кроссбраузерного использования события DOMContentLoaded. Вернее методы эмуляции работы этого события.

Самые, пожалуй, популярные методы запуска кода по завершении построения DOM-дерева — это использование JavaScript-фреймворков. В jQuery это делается вот так:

$(document).ready(function(){ // Код который выполнится сразу по завершении построения DOM-дерева });

Или ещё короче:

$(function(){ // Код который выполнится сразу по завершении построения DOM-дерева })

В MooTools это выглядит так:

window.addEvent('domready', function() { alert('The DOM is ready!'); });

Но иногда подключать целую библиотеку только ради DOMContentLoaded — это через чур. Тогда я решил поискать готовые решения эмуляции этого события.

Вначале я наткнулся на уже упомянутый выше скрипт от Diego Perini ContentLoaded. Скрипт основывается на определении браузера и, в зависимости от того какой браузер использует клиент, мы используем тот или иной метод для скорейшего запуска обработчика после того, как готово DOM-дерево.

Для Safari версий ниже 3.1 скрипт проверяет свойство document.readyState. Если значение этого свойства равно complete или loaded, то запускается обработчик события, в противном случае проверка выполняется повторно через 10 милисекунд.

В IE для проверки загруженности DOM-дерева используется проприетарная функция doScroll(), которая выкинет ошибку, если попытаться запустить её до того, как будет построено DOM-дерево. doScroll()вызывается до тех пор, пока не перестанет выдавать ошибку и тогда запускается необходимый код.

Для браузеров, которые не поддерживают DOMContentLoaded и не являются Internet Explorer'ом, обработчик вешается на событие onload.

Помимо решения от Diego Perini, я наткрнулся на статью «Кроссбраузерное событие onDOMContentLoaded».

Короче, решение от Diego Perini, на мой взгляд, не самое лучшее. Есть более толковый способ и он подробно расписан в статье «Кроссбраузерное событие onDOMContentLoaded».

Diego Perini использует определение браузера (browser detection) и в зависимости от того, какой браузер у пользователя, используется тот или иной подход. В статье на javascript.ru используется немного другой подход. Он выглядит приблизительно так: для браузеров кроме IE обработчик вешается одновременно и на событие DOMContentLoaded и на onload и срабатывает только один раз. Если сработало DOMContentLoaded, то по событию onload этот обработчик уже не вызывается. Если же браузер не поддерживает DOMContentLoaded, то обработчик сработает по событию onload. Хоть в IE до 9-ой версии и нет события DOMContentLoaded, есть возможность запустить обработчик раньше события onload. Для это в IE используется проприетарная функция doScroll(), которая выкинет ошибку, если попытаться запустить её до того, как будет построено DOM-дерево. Таким образом в IE мы вызываем обработчик, когда doScroll() перестанет выдавать ошибку.

Вот собственно и всё.