CSS slide animation with angularjs

2019-08-14 23:58发布

问题:

I'm trying to animate a div using ng-show with CSS3 transitions. There are 2 divs: One in the foreground and another hidden behind it. The hidden div should slide up when the user mouse's over the foreground div. It should also remain shown if the users cursor moves over the slide div. If the users cursor leaves the slide div or the foreground div, it should slide back down. It doesn't seem to work correctly though. Here's a plunker: http://plnkr.co/edit/C1RaDTOXwpEMECGMkt19?p=preview

Is the css correct?

div#cover {
  background-color: lightblue;
  width: 90px;
  height: 30px;
  position:absolute;
  bottom: 0px;
  z-index:10;
}


.slide {
  background-color: white;
  width: 90px;
  height: 30px;
  position:absolute;
  bottom: 0px;
  z-index:5;
}

.slide.ng-hide-add, .slide.ng-hide-remove { 
    transition: bottom 1s ease;
}

.slide.ng-hide-remove-active {
    bottom: 30px
}

.slide.ng-hide-add-active {
    bottom: 0px
}

Any ideas?

回答1:

You only need two states:

  1. Shown
  2. Hidden

Let the base slide class define the state for shown (30px from bottom):

.slide {
  background-color: white;
  width: 90px;
  height: 30px;
  position: absolute;
  bottom: 30px;
  z-index: 5;
  transition: 1s ease bottom !important;
  display: block !important;
}

When the expression used in the ng-show directive is evaluated to false the hidden state will be activated and the class ng-hide will be added to the element by Angular.

Use that class to decorate the base class and define the hidden state (0px from bottom):

.slide.ng-hide {
  bottom: 0;
}

This means the two states will have the following classes when active:

  1. Shown: slide
  2. Hidden: slide ng-hide

As you see the slide class is always present, which is why the transition is put there.

You must use !important on the transition otherwise if you move the cursor back and forth over the element Angular will override it with transition: none briefly, which will cause the transition to interrupt and the element to snap into its final position.

You must also use display: block !important in the slide class to override the default behavior of ng-hide, which is display: none.

Demo: http://plnkr.co/edit/WN8v2riSYhhMyOgbZiWO?p=preview

Note: Personally I wouldn't recommend using ng-mouseenter or ng-mouseleave for this. Everytime they trigger the entire digest cycle and all watchers will be executed multiple times. The alternative would be to create a directive that uses event listeners to add/remove classes manually.