Профессиональные курсы: Практика верстки HTML JavaScript для начинающих Программирование на PHP Онлайн-курсы по веб-технологиям

Анимация со сменой прозрачности: Fade In, Fade Out

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

Задача

Чтобы fade-анимация не ставила в тупик JavaScript-разработчиков принято решение написать небольшое руководство как это сделать малой кровью, не подключая громоздкие js-фреймворки. Что нам необходимо:

  1. Знать как кроссбраузерно задавать прозрачность
  2. Сделать таймер, чтобы работала анимация

Первая задача (наиболее трудоемкая), к счастью, успешно решена Игорем Цыгырлашем в статье CSS прозрачность (css opacity, javascript opacity). Там же есть небольшой черный ящик в виде библиотеки для плавного изменения прозрачности элементов, но мне она не приглянулась из-за нескольких минусов.

Объект

Итак, после некоторой переработки кода с tigir.com и на основе собственной практики написания фейд-эффектов получилась такая библиотечка:

var fade = { // Namespace
    step    : 0.05,
    delay   : 20, // ms
    timer   : null,
    setOpacity : function(elem, nOpacity) {
        if (typeof elem == 'string') elem = document.getElementById(elem);
        var props = ['MozOpacity', 'KhtmlOpacity', 'opacity'];
        for (var i in props) {
            if (typeof elem.style[props[i]] == 'string') {
                elem.style[props[i]] = nOpacity;
                return;
            }
        }
        // IE 6+
        try {
            nOpacity = 100 * parseFloat(nOpacity);
            if ((oAlpha = elem.filters['DXImageTransform.Microsoft.alpha'] || elem.filters.alpha)) oAlpha.opacity = nOpacity;
            else elem.style.filter += "progid:DXImageTransform.Microsoft.Alpha(opacity="+nOpacity+");";
        } catch (e) {
            // IE <= 5.5 OR Opera < 9 OR another browser. Do nothing
        }
    },
    _out : function(id, from, to, callback) {
        from -= this.step;
        from = from <= to ? to : from;
        if (this.doit(id, from, to, callback))
            this.timer = setTimeout("fade._out('"+id+"', "+from+", "+to+", '"+(callback ? callback : '')+"')", this.delay);
    },
    _in : function(id, from, to, callback) {
        from += this.step;
        from = from >= to ? to : from;
        if (this.doit(id, from, to, callback))
            this.timer = setTimeout("fade._in('"+id+"', "+from+", "+to+", '"+(callback ? callback : '')+"')", this.delay);
    },
    doit : function(id, from, to, callback) {
        this.setOpacity(id, from);
        clearTimeout(this.timer);
        if (from == to) {
            if (callback) eval(callback+'()');
        } else return true;
    }
}

Сразу же смотрим скрипт в работе!

Разберем немного сам объект:

  • fade — это неймспейс, введен исключительно для того, чтобы не было случайного пересечения глобально объявленных переменных или функций с уже имеющимся на вашем сайте кодом.
  • setOpacity — самый главный метод объекта fade, который и задает прозрачность элемента. В качестве первого аргумента принимает ссылку на элемент или его идентификатор. Второй аргумент — значение прозрачности, которое необходимо установить. Метод появился на свет благодаря функциям getOpacityProperty и setOpacityProperty с tigir.com
  • _in и _out — методы для анимации появления и исчезновения соот-но. Принимают в качестве аргументов идентификатор элемента, значения "от" и "до" и функцию обратного вызова (необязательный аргумент). В приводимом выше примере у кнопки следующий обработчик клика:
    fade._out('imgId', 1, 0, 'stopHide');
    Читается так: "необходимо уменьшать прозрачность элемента с идентификатором 'imgId' от единицы до нуля и после достижении нуля вызвать функцию с именем 'stopHide'". Так оно и работает.
    Важно! Все аргументы кроме последнего являются обязательными.
  • Изменение прозрачности происходит пошагово и его скорость регулируется двумя свойствами: step — шаг между двумя изменениями и delay — задержка между итерациями. Изменяйте их для увеличения или снижения скорости анимации.

Что нового в коде по сравнению с примером Игоря Цыгырлаша? Во-первых оптимизированный метод setOpacity, но это только технически, ничего принципиально нового там нет. А во-вторых, добавлены колбэки, необходимость которых возникала в каждом случае практического применения описанных эффектов.

Да, и еще, такая простая структура объекта может подойти для любой другой анимации. Можно добавить метод плавно уменьшающий высоту объекта — и еще один эффект готов.

Проверено в:

WIN: IE6, IE7, FF1.5+, Safari 3, Opera 9+, Chrome

Точно не будет работать в ИЕ5.5 (и ниже) и в Операх ниже девятой версии.

Александр Бурцев 5 ноября 2008

© Все права на данную статью принадлежат порталу fastcoder.org. Перепечатка в интернет-изданиях разрешается только с указанием автора и прямой ссылки на оригинальную статью. Перепечатка в печатных изданиях допускается только с разрешения редакции.

Комментарии

Octane 5 ноября 2008, 21:15 #
А почему в IE5.5 не будет работать? Нет я конечно не говорю, что всё ещё нужно поддерживать этого динозавра, просто интересно. У меня в IE5.5 из пакета MultipleIEs работает прозрачность.
 
Bur 5 ноября 2008, 21:43 #
Свою девелоперскую практику я начинал при широкой распространенности ИЕ6, поэтому как выставлять прозрачность для ИЕ5.5 не помню. Когда стал проверять объект понял, что в ИЕ5.5 не работает (даже скрипты с tigir.com не пашут, хотя поддержка ИЕ5.5 заявлена). Ну а дальше вы сами всё объяснили, поддерживать этого динозавра не имеет смысла, вот я и забил. Проверял в IE Tester, кстати.
 
dwkwa 23 ноября 2008, 12:06 #
Красота и элегантность!
Спасибо!

P.S.:
* для "elem.style.filter += "progid:..." - хорошо бы ещё ";" добавить
(на случай очередной добавки)
* также не очень однозначно условие:
----------
if(oAlpha = elem.filters['DXImageTransform.Microsoft.alpha'] || elem.filters.alpha))
oAlpha.opacity = nOpacity;
----------
Получается, что даже если "oAlpha = elem..." будет FALSE, но elem.filters.alpha = TRUE, то мы спокойно можем неизвесному oAlpha в opacity записать значение?

Но в общем очень приятно видеть такие коды. =оР
 
Bur 23 ноября 2008, 22:14 #
За точку с запятой спасибо!
С условием же, всё в порядке. Cтрока
oAlpha = elem.filters['DXImageTransform.Microsoft.alpha'] || elem.filters.alpha

вернет ссылку на опасити-фильтр, либо null.
 
Dicht 3 декабря 2008, 10:45 #
Спасибо, очень подробное и интересное решение.
Мне кажется, или в названии статьи ошибка ?
 
Bur 3 декабря 2008, 11:42 #
Велкам!

Скопировал: "Анимация со сменой прозрачности: Fade Id, Fade Out"
Вроде всё верно.
 
Dicht 3 декабря 2008, 16:13 #
Может быть я просто чего-то не понял, но по моему должно быть так: "Анимация со сменой прозрачности: Fade In, Fade Out"
 
Bur 3 декабря 2008, 16:24 #
IN!
Спасибо, поправил. Первый раз не заметил.
 
ExTRANE 29 ноября 2009, 20:27 #
Можно вопрос ...

Как его можно установить на сайт ... я хотел зделать с помощью этого кода меню которое будет всегда сидеть с боку сайта и когда пользователь нажмет на кнопочку оно появиться ...

Так вот ... я не могу его установить на сайт .... как нужно, создать страницу пример: aammd.html , а дальше что ... потому что когда я пихаю его в мой header.tpl картинки и кнопки есть а вот ефекта никакого, У мя на сайте smarty .. тоесть вся инфа на .tpl ... . php)
 
Bur 30 ноября 2009, 14:43 #
1) Подключить скрипт (объект fade).
2) Скрыть меню с помощью стилей меню (style="display:none").
3) На кнопку повесить обработчик, принимающий в качестве аргумента идентификатор блока с меню:
function(menuId) {
     document.getElementById(menuId).style.display = '';
     fade._in(menuId, 0, 1);
}
-------------------------------------------------------
Или воспользоваться методом fadeIn библиотеки jQuery.
 
 
Rambler's Top100 Flede HTML valid CSS valid