Анимация тостов с использованием чистого javascript - PullRequest
1 голос
/ 17 апреля 2020

Я пытаюсь сделать упрощенную версию тоста googles из их коллекции материалов.

Я все сузил до этого.

Как я могу вставлять и выдвигать тост по вертикали, используя только обычный javascript?

$(document).ready(function(){
  $('.trigger').click(function(){
    if ( $('.Mh0NNb').css('visibility') == 'hidden' )
      $('.Mh0NNb').css('visibility','visible');
    else
      $('.Mh0NNb').css('visibility','hidden');
  });
});
.Mh0NNb {
    background-color: #323232;
    bottom: 0;
    box-sizing: border-box;
    box-shadow: 0 6px 10px 0 rgba(0,0,0,0.14),0 1px 18px 0 rgba(0,0,0,0.12),0 3px 5px -1px rgba(0,0,0,0.2);
    color: #fff;
    display: flex;
    flex-direction: column;
    font-size: 14px;
    left: 0;
    min-height: 48px;
    position: fixed;
    right: 0;
    transform: translate(0,100%);
    visibility: hidden;
    z-index: 99999;
}

.M6tHv {
    -webkit-box-align: center;
    box-align: center;
    align-items: center;
    align-content: center;
    display: flex;
    flex-direction: row;
    min-height: inherit;
    padding: 0
}

.aGJE1b {
    box-flex: 1;
    flex-grow: 1;
    flex-shrink: 1;
    line-height: normal;
    overflow: hidden;
    padding: 14px 24px;
    text-overflow: ellipsis;
    word-break: break-word
}

.x95qze {
    align-self: center;
    color: #eeff41;
    box-flex: 0;
    flex-grow: 0;
    flex-shrink: 0;
    float: right;
    text-transform: uppercase;
    font-weight: 500;
    display: inline-block;
    cursor: pointer;
    outline: none;
    padding: 14px 24px
}

@media screen and (min-width: 481px) {
    .Mh0NNb {
        min-width:288px;
        max-width: 568px;
        border-radius: 2px
    }

    .Mp2Z0b {
        left: 24px;
        margin-right: 24px;
        right: auto
    }

    .VcC8Fc {
        left: 50%;
        right: auto;
        transform: translate(-50%,100%)
    }

    .Mp2Z0b.misTTe {
        bottom: 24px
    }

    .VcC8Fc.misTTe {
        bottom: 0;
        transform: translate(-50%,0)
    }

    .M6tHv {
        padding: 0
    }

    .aGJE1b {
        padding-right: 24px
    }
}

@media screen and (max-width: 480px) {
    .xbgI6e .aGJE1b,.xbgI6e .x95qze {
        padding-bottom:24px;
        padding-top: 24px
    }
}

@media screen and (min-width: 481px) and (max-width:568px) {
    .Mh0NNb {
        max-width:90%
    }
}

@media screen and (min-width: 569px) {
    .Mh0NNb {
        max-width:568px
    }
}

.Mh0NNb.Mh0NNb {
    background-color: #202124;
    border-radius: 4px 4px 0 0
}

.aGJE1b.aGJE1b {
    color: #bdc1c6;
    font-weight: 500;
    line-height: 1.4
}

.x95qze.x95qze {
    color: #669df6;
    text-transform: capitalize;
    font-family: 'Google Sans',Roboto,RobotoDraft,Helvetica,Arial,sans-serif
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="Mh0NNb VcC8Fc misTTe">
    <div class="M6tHv">
        <div class="aGJE1b">Contact details updated</div>
        <div class="dnmu6e" tabindex="0"></div>
        <div class="x95qze" role="button" tabindex="0" aria-describedby="J9Hpafc51">Undo</div>
        <div class="dnmu6e" tabindex="0"></div>
    </div>
</div>
<button class="trigger">Toggle Info Box!</button>

Ответы [ 2 ]

1 голос
/ 17 апреля 2020

Переключение класса для переключения CSS анимированных стилей:

  • Привязка события нажатия к обработчику вызова кнопки function toasted() при срабатывании:

    document.querySelector('.arrow').onclick = toasted;
    
  • Обработчик должен передать объект события, а затем определить, на что нажал пользователь, используя свойство e.target.

    function toasted(e) {
      let clicked = e.target;
      if (clicked.matches('.arrow')) {//...
    
  • Как только будет установлено, что кнопка была нажата для переключения класс .show на кнопке (необязательно) и тост (обязательно).

    //...
      /*
      toast follows button use .nextElementSibling property
      button follows toast use .previousElementSibling property
      */ 
      let toast = clicked.nextElementSibling; 
      toast.classList.toggle('show');
      clicked.classList.toggle('show');
      //...
    

Анимация проста CSS:

  • Установить sh селекторы в исходном состоянии (ie скрыто)

    .toast {
      ...
      transform: translateX(0%);
      opacity: 0;
      transition: 0.5s
    }
    

    transform: translateX(0%) означает сдвиг влево / вправо на 0 расстояния.
    opacity: 0 означает, что он есть, но не visible.
    transition: 0.5s означает, что если и когда эти 2 свойства изменят значения, сделайте так, чтобы это заняло полсекунды. Вот что движет анимацией. В противном случае изменения будут мгновенными.

  • Следующий набор правил CSS предназначен для нового состояния при добавлении класса .show:

    .toast.show {
      transform: translateX(100%);
      opacity: 1;
    }
    

    transform: translateX(100%); означает перемещение тоста на 100% его собственной длины слева направо. Если вы хотите справа налево, то translateX(100%), сверху вниз translateY(100%), снизу вверх translateY(-100%).
    opacity: 1 ежу понятно.


Демо

document.querySelector('.arrow').onclick = toasted;

function toasted(e) {
  let clicked = e.target;
  if (clicked.matches('.arrow')) {
    let toast = clicked.nextElementSibling;
    toast.classList.toggle('show');
    clicked.classList.toggle('show');
  }
}
.arrow {
  transform: rotate(0deg);
  cursor: pointer;
  background: none;
  border: 0;
  padding: 10px;
  transition: transform 0.3s;
}

.arrow.show {
  transform: rotate(180deg);
}

.toast {
  display: inline-block;
  transform: translateX(0%);
  opacity: 0;
  transition: 0.5s;
}

.toast.show {
  transform: translateX(100%);
  opacity: 1;
}
<button class='arrow'>◀</button>
<p class='toast'>HEY!</p>
1 голос
/ 17 апреля 2020

В части JS переключите (или добавьте / удалите) класс CSS.

Затем используйте свойства CSS transform и opacity, чтобы создать эффект скольжения + затухания, и используйте transition, чтобы сделать их анимированными:

document.addEventListener('DOMContentLoaded', () => {  
  document.querySelector('.trigger').addEventListener('click', () => {
    document.querySelector('.Mh0NNb').classList.toggle('active')
  })
})
.Mh0NNb {
    background-color: #323232;
    bottom: 0;
    box-sizing: border-box;
    box-shadow: 0 6px 10px 0 rgba(0,0,0,0.14),0 1px 18px 0 rgba(0,0,0,0.12),0 3px 5px -1px rgba(0,0,0,0.2);
    color: #fff;
    display: flex;
    flex-direction: column;
    font-size: 14px;
    left: 0;
    min-height: 48px;
    position: fixed;
    right: 0;
    transform: translate(0,100%);
    opacity: 0;
    z-index: 99999;
    transition: 0.5s transform, 1s opacity;
}
.Mh0NNb.active {
    transform: translate(0,0);
    opacity: 1;
}
.M6tHv {
    -webkit-box-align: center;
    box-align: center;
    align-items: center;
    align-content: center;
    display: flex;
    flex-direction: row;
    min-height: inherit;
    padding: 0
}

.aGJE1b {
    box-flex: 1;
    flex-grow: 1;
    flex-shrink: 1;
    line-height: normal;
    overflow: hidden;
    padding: 14px 24px;
    text-overflow: ellipsis;
    word-break: break-word
}

.x95qze {
    align-self: center;
    color: #eeff41;
    box-flex: 0;
    flex-grow: 0;
    flex-shrink: 0;
    float: right;
    text-transform: uppercase;
    font-weight: 500;
    display: inline-block;
    cursor: pointer;
    outline: none;
    padding: 14px 24px
}

@media screen and (min-width: 481px) {
    .Mh0NNb {
        min-width:288px;
        max-width: 568px;
        border-radius: 2px
    }

    .Mp2Z0b {
        left: 24px;
        margin-right: 24px;
        right: auto
    }

    .VcC8Fc {
        left: 50%;
        right: auto;
        transform: translate(-50%,100%)
    }

    .Mp2Z0b.misTTe {
        bottom: 24px
    }

    .VcC8Fc.misTTe {
        bottom: 0;
        transform: translate(-50%,100%)
    }
    .VcC8Fc.active {
        transform: translate(-50%,0);
        opacity: 1;
    }

    .M6tHv {
        padding: 0
    }

    .aGJE1b {
        padding-right: 24px
    }
}

@media screen and (max-width: 480px) {
    .xbgI6e .aGJE1b,.xbgI6e .x95qze {
        padding-bottom:24px;
        padding-top: 24px
    }
}

@media screen and (min-width: 481px) and (max-width:568px) {
    .Mh0NNb {
        max-width:90%
    }
}

@media screen and (min-width: 569px) {
    .Mh0NNb {
        max-width:568px
    }
}

.Mh0NNb.Mh0NNb {
    background-color: #202124;
    border-radius: 4px 4px 0 0
}

.aGJE1b.aGJE1b {
    color: #bdc1c6;
    font-weight: 500;
    line-height: 1.4
}

.x95qze.x95qze {
    color: #669df6;
    text-transform: capitalize;
    font-family: 'Google Sans',Roboto,RobotoDraft,Helvetica,Arial,sans-serif
}
<div class="Mh0NNb VcC8Fc misTTe">
    <div class="M6tHv">
        <div class="aGJE1b">Contact details updated</div>
        <div class="dnmu6e" tabindex="0"></div>
        <div class="x95qze" role="button" tabindex="0" aria-describedby="J9Hpafc51">Undo</div>
        <div class="dnmu6e" tabindex="0"></div>
    </div>
</div>
<button class="trigger">Toggle Info Box!</button>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...