2016-11-27 5 views
7

Хорошо, у меня есть ситуация, когда я в основном построил небольшое раскрывающееся окно уведомления, которое происходит, когда пользователь что-то делает, в конце он переходит в состояние opacity: 0;.Удаление классов из элемента без влияния на выполняемые css-переходы

Однако, поскольку пользователь может щелкнуть что-то еще, что приведет к появлению этого окна уведомления снова, я пытаюсь найти способ вернуть его к нормальной работе, не влияя на какие-либо промежуточные переходы и пытаясь сохранить анимацию CSS, а не JavaScript.

CodePen:http://codepen.io/gutterboy/pen/WoEydg

HTML:

<a href="#">Open Notify Window</a> 

<div id="top_notify" class="top-notify"> 
    <div class="container-fluid"> 
     <div class="row"> 
      <div class="content col-xs-12"> 
       <div class="alert" role="alert"></div> 
      </div> 
     </div> 
    </div> 
</div> 

SCSS:

body { 
    text-align: center; 
    padding-top: 150px; 
} 

.top-notify { 
    position: fixed; 
    top: 0; 
    width: 100%; 
    z-index: 9999; 

    .content { 
     text-align: center; 
     background-color: transparent; 
     transform-style: preserve-3d; 
    } 

    .alert { 
     display: inline-block; 
     transform: translateY(-100%); 
     min-width: 250px; 
     max-width: 500px; 
     border-top-left-radius: 0; 
     border-top-right-radius: 0; 

     &.visible { 
      transform: translateY(0%); 
      transition: 0.8s 0s, opacity 1s 3.8s; 
      opacity: 0; 
     } 

    } 

} 

JS:

$('a').on('click', function(e){ 
    e.preventDefault(); 
    myFunc(); 
}); 

function myFunc() { 

    // Set file to prepare our data 
    var loadUrl = "https://crossorigin.me/http://codepen.io/gutterboy/pen/ObjExz.html"; 

    // Run request 

    getAjaxData(loadUrl, null, 'POST', 'html') 

      .done(function(response) { 

       var alert_el = $('#top_notify').find('.alert'); 

       // Update msg in alert box 
       alert_el.text(response); 
       alert_el.addClass('alert-success'); 

       // Slide in alert box 
       alert_el.addClass('visible'); 

      }) 

      .fail(function() { 
       alert('Problem!!'); 
      }); 

    // End 

} 

function getAjaxData(loadUrl, dataObject, action, type) { 

    return jQuery.ajax({ 
     type: action, 
     url: loadUrl, 
     data: dataObject, 
     dataType: type 
    }); 

} 

Я знаю, что может сбросить его обратно в нормальное русло, делая это в JS:

$('#top_notify').find('.alert').removeClass().addClass('alert'); // The classes it ends up with vary 

... однако делать это удаляет классы до перехода закончен выведением непрозрачности, и он просто исчезает сразу.

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

Есть ли способ сделать это, сохраняя анимацию, выполненную с помощью CSS, или мне нужно будет перейти к использованию jQuery's animate, чтобы я мог запустить процедуру сброса после завершения анимации?

+0

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

+0

Эта статья немного устарела, но может быть применена здесь: https://css-tricks.com/pop-from-top-notification/ –

+0

@NathanielFlick Ну, я бы предпочел использовать только одно окно для всех случаев вместо того, чтобы создавать дополнительные; Я предполагаю, что это вариант. Также спасибо за ссылку. – Brett

ответ

1

Хорошо, я придумал простое решение после того, как придумал изогнутый один га.

Простое решение, которое я должен был придумать, в первую очередь было удаление любые дополнительные добавленные классы перед темajax вызова; Я слишком сосредоточен на том, чтобы делать это в блоке ajax, и, конечно, это не сработало, но пока я не начал играть с другим решением, я никогда не пробовал.

В любом случае, простое решение просто перенести этот код:

var alert_el = $('#top_notify').find('.alert'); 

... над ajax вызова, а не внутри него.

Затем, добавив это прямо под ним:

alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning'); 

С полным кода функции существами:

function myFunc() { 

    // Set file to prepare our data 
    var loadUrl = "https://crossorigin.me/http://codepen.io/gutterboy/pen/ObjExz.html"; 

    var alert_el = $('#top_notify').find('.alert'); 

    alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning'); 

    // Run request 

    getAjaxData(loadUrl, null, 'POST', 'html') 

      .done(function(response) { 

       // Update msg in alert box 
       alert_el.text(response); 
       alert_el.addClass('alert-success'); 

       // Slide in alert box 
       alert_el.addClass('visible'); 

      }) 

      .fail(function() { 
       alert('Problem!!'); 
      }); 

    // End 

} 

CodePen:http://codepen.io/gutterboy/pen/xRXbXy

Другим решением я придумал, в то время как теперь мне действительно не нужно, я думал, что все равно отправлю его в случае, если он мне пригодится (или кто-то еще) в будущее.

Это не удалить visible класс после того, как анимация закончена (поскольку нет никакого способа, которым я не знаю, чтобы предупредить JS, когда это делается), но visible класс - , который я хотел бы изменить название, если вы используете этот метод - не добавляет никаких новых стилей, он просто запускает анимацию.

Вот как я это сделал:

JavaScript остается таким же, как выше решения, все это в CSS.

TLDR;

В основном использует несколько анимаций CSS для управления различными состояниями во время выполнения эффекта; CodePen внизу.

Изменения в классе .visible и добавлении некоторых @keyframes.

.Visible класс:

&.visible { 
    animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s; 
} 

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

Теперь давайте разберем этот код:

Мы работаем 3 различных анимация здесь, и это важно отметить, что они не работают один за другим - это значит, что они не ждать, пока один не будет закончен, пока она запускает следующий, поэтому нам нужно было указать настройки delay.

Итак, сначала вверх, мы начнем с slideDown анимации:

slideDown 0.8s 0s

Если вы новичок в анимации в CSS, то в основном то, что это делает устанавливает задержку 0s, прежде чем он начнет работать и анимация работает для 0.8s, и это анимация:

@keyframes slideDown { 
    0% { 
     transform: translateY(-100%); 
    } 
    100% { 
     transform: translateY(0%); 
    } 
} 

Так, довольно просто, скользит вниз с transform из -100% - 0%, и эта анимация принимает 0.8s, как мы установили в нашем обращении к этой анимации.

Теперь я хотел этого, чтобы остаться видимую за 3 секунды, прежде чем он начал исчезать, но у нас есть проблема; как только анимация заканчивается, она возвращается к стандартным стилям, что в нашем случае означает, что оно исчезает, когда оно возвращается к transform: translateY(-100%), поскольку у нас нет дополнительных стилей в классе .visible, и мы не можем добавлять туда лишние стили, как тогда мы не сможем вернуть . Сброс обратно в исходное состояние (стиль мудрый).

Но что мы будем делать? Анимация fadeAway не начинается еще 3 секунды, и на данный момент у нее нет ничего, чтобы исчезнуть (ну, но это не так, но вы не можете видеть ее, поскольку она скрыта).

Решение этой задачи заключается в добавлении еще одной анимации, которая технически ничего не оживляет, она просто сохраняет ее до тех пор, пока не начнется анимация fadeAway.

Вот где мы получаем:

keepThere 3s 0.8s

Теперь, вспоминая настройки нашего fadeAway анимации являются: fadeAway 1s 3.8s это означает, что мы имеем 3 секунды до этого анимация собирается начать и, следовательно, до того мы можем управлять любым стилем с ним.

Так вот где эти значения параметров приходит - мы устанавливаем задержку 0.8s так keepThere анимация не начинается до тех пор, slideDown один не закончил; Затем мы устанавливаем длительность для 3s, чтобы противостоять в течение времени ожидания, пока fadeAway начинается анимации, и это keepThere анимация:

@keyframes keepThere { 
    0%, 100% { 
     transform: translateY(0%); 
    } 
} 

Поскольку она имеет ту же начальную и конечную укладку мы объединить его в один селектор 0%, 100% и, как вы можете видеть, это делает то, что, как он говорит, делает, сохраняет элемент видимым для заданной продолжительности 3s, пока мы не сможем управлять стилем с помощью анимации fadeAway.

Я думаю, технически вы могли бы объединить эту функциональность в fadeAway анимации, если вы хотите сделать математику на то, что% равно 3 секунды и, следовательно, знать, когда начинать выцветания элемент прочь.

Наконец мы имеем fadeAway анимации:

fadeAway 1s 3.8s

Теперь, как мы уже говорили выше, мы уже знаем, почему мы установили delay в 3.8s, то 0.8s смещение, чтобы позволить slideDown анимации для запуска и дополнительную задержку 3s, так как мы хотим, чтобы элемент был видимым до тех пор, пока он не начнет исчезать, а затем, конечно, затухание займет 1s.

анимация для этого:

@keyframes fadeAway { 
    0%, 100% { 
     transform: translateY(0%); 
    } 
    0% { 
     opacity: 1; 
    } 
    100% { 
     opacity: 0; 
    } 
} 

Теперь, так как keepThere анимация завершена, мы должны убедиться, чтобы сохранить видимый элемент, так что замирания есть что-то видимое на самом деле неувядающий, поэтому мы не забудьте включить стиль transform: translateY(0%); в качестве значения от начала до конца; после этого совершенно очевидно, что он делает, я думаю.

Положите все это вместе, и вы получите:

.top-notify { 
    position: fixed; 
    top: 0; 
    width: 100%; 
    z-index: 9999; 

    .content { 
     text-align: center; 
     background-color: transparent; 
     transform-style: preserve-3d; 
    } 

    .alert { 
     display: inline-block; 
     transform: translateY(-100%); 
     min-width: 250px; 
     max-width: 500px; 
     border-top-left-radius: 0; 
     border-top-right-radius: 0; 

     &.visible { 
      animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s; 
     } 

    } 

} 

@keyframes slideDown { 
    0% { 
     transform: translateY(-100%); 
    } 
    100% { 
     transform: translateY(0%); 
    } 
} 

@keyframes keepThere { 
    0%, 100% { 
     transform: translateY(0%); 
    } 
} 

@keyframes fadeAway { 
    0%, 100% { 
     transform: translateY(0%); 
    } 
    0% { 
     opacity: 1; 
    } 
    100% { 
     opacity: 0; 
    } 
} 

CodePen:http://codepen.io/gutterboy/pen/QGqwBg

Тогда, конечно, чтобы быть в состоянии запустить его снова класс должен быть повторно добавлен и, следовательно, был цель удаления класса .visible в начале каждого прогона (перед вызовом ajax), а затем, когда он снова добавляется во время вызова ajax, он снова запускает.

Благодаря @Nathaniel Flick для обмена ссылку, которая привела меня на этот путь, чтобы начать с :)

Ну, надеюсь, что пригодится для кто видя, как я больше не собираюсь использовать эту опцию ха!