11 августа 2011 г.

text-shadow для Internet Explorer

Привет, всем.

Лучшая из виденных мною реализаций свойства text-shadow в IE без использования JavaScript. Встречайте — CSS3 Text-Shadow – Can It Be Done in IE Without JavaScript? от Zoltan Hawryluk.
На сайте этого автора можно найти ещё интересные вещи.

Кроссбраузерные обработчики событий

addEvent() от Дина Эдвардса

Проверенное мной лаконичное решение. Использует DOM Level 0 Events и никакого feature detection'а. Когда мы вешаем обработчик с помощью addEvent() на элемент, в качестве свойства этого элемента добавляется объект events, внутри которого в массив добавляется функция-обработчик. Если этот массив уже существует, то к уже имеющимся обработчикам добавляются новые.

Из коробки при использовании функции removeEvent() необходимо указывать в качестве третьего аргумента ссылку на ранее установленный обработчик. Т.е. нет возможности удалять анонимные функции-обработчики. Но это легко исправляется слегка изменив функцию removeEvent():

function removeEvent(element, type, handler) { // delete the event handler from the hash table if (element.events && element.events[type]) { (!handler) ? delete element.events[type] : delete element.events[type][handler.$$guid]; } };

Теперь если мы не указали ссылку на функцию-обработчик в качестве третьего аргумента, то удаляются все обработчики заданного события.

Ссылки по теме

1 марта 2011 г.

Псевдо-класс :active и Internet Explorer

Заметил одну особенность использования псевдо-класса :active в Internet Explorer'е. Стили присвоенные с помощью псевдо-класса :active в этом браузере сработают только если вы кликаете непосредственно по элементу, которому был указан псевдо-класс, но не по его дочерним элементам.

Рассмотрим пример:

<p>Просто текст с <span>элементом</span> внутри.</p>

CSS:

p:active { text-decoration: underline; }

В IE текст внутри параграфа станет подчеркнутым только если вы кликните непосредственно по элементу <p>, а не по span'у внутри него. Это не касается остальных браузеров. В Safari, Google Chrome, Opera и Firefox текст внутри параграфа станет подчеркнутым не зависимо от того, нажали ли вы на дочерний элемент или на сам параграф.

Аналогично в IE не сработает следующий css-код:

p:active span { text-decoration: underline; }

Текст внутри элемента <span> не станет подчеркнутым если нажать на элемент <p>, в то время как в остальных браузерах текст будет подчеркнутым.

Не знаю что говорит на этот счет спецификация CSS (подозреваю что ничего), но мне кажется что Firefox и остальные браузеры более предсказуемо и правильно обрабатываю выше приведенные примеры нежели IE.

Описанный выше код касается всех существующих на данный момент версий Internet Explorer'а — 7, 8, 9 RC. Собственно IE7 вообще понимает псевдо-класс :active только для элемента <a>.

В качестве демонстрации можете потыкать по элементам внутри параграфов на этой страничке — http://quirksmode.org/css/hover.html.

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() перестанет выдавать ошибку.

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