动态添加变换 - 最后还原为原始值

时间:2017-02-19 10:57:11

标签: javascript css transform

我正在尝试动态添加transform: translate3d来移动div,但在转换结束时,div会恢复到原始位置。我正在添加一个新样式表并使用insertRule()。可能导致这种情况的任何想法?

以下是a fiddle

slideshow = (function() {
  function slideshow() {
    var _this = this;
    this.divMiddle;
    this.divLarge = []; // holds full sized image
    this.largeSize = [];
    this.slide = -1;
    this.oldSlide = -1;
    this.img = [];

    this.divMiddle = document.createElement("div");
    this.divMiddle.id = "divMiddle";
    this.divMiddle.style.position = "relative"
    this.divMiddle.style.width = "500px";
    this.divMiddle.style.height = "400px";
    this.divMiddle.style.border = "1px solid black";
    document.body.appendChild(this.divMiddle);
    document.getElementById("next").addEventListener("click", function() {
      _this.transitionSlides(1)
    });
    document.getElementById("prev").addEventListener("click", function() {
      _this.transitionSlides(-1)
    });

    this.oldSlide = -1;
    this.slide = -1;
    this.transitionSlides(1);
  }

  // transition between slides - fading new one in and old one out
  slideshow.prototype.transitionSlides = function(direction) {
    // if not the first one loaded, will do transition
    var begin, end;
    this.oldSlide = this.slide;
    this.slide += direction;
    if (this.slide > this.oldSlide) {
      this.createImage();
    }
    if (CSSRule.KEYFRAMES_RULE) {
      var prefix = ""
    } else if (CSSRule.WEBKIT_KEYFRAMES_RULE) {
      var prefix = "-webkit-"
    }
    var style = document.createElement("style");
    document.head.appendChild(style);

    // fade out the old slide
    if (this.oldSlide >= 0) {
      // fade(this.divLarge[this.oldSlide], 1, .1, 20);      
      this.divLarge[this.oldSlide].style.opacity = ".3";

      var oldMargin = (parseInt(this.divMiddle.style.width) - parseInt(this.largeSize[this.oldSlide].displayWidth)) / 2;
      begin = 0;
      if (direction == 1) {
        // next
        // move existing slide from left to right
        end = (parseInt(this.largeSize[this.oldSlide].displayWidth) + oldMargin);
      } else {
        // prev
        // move existing slide from right to left
        end = -(parseInt(this.largeSize[this.oldSlide].displayWidth) + oldMargin + 1);
      }
      var rule = "@" + prefix + "keyframes moveOld {" +
        "0% {" + prefix + "transform: translate3d(" + begin + "px, 0, 0); }" +
        "100% {" + prefix + "transform: translate3d(" + end + "px, 0, 0); }" +
        "}";
      style.sheet.insertRule(rule, 0);

      var rule2 = "#" + this.divLarge[this.oldSlide].id + "{" + prefix + "animation: moveOld 3s linear" + "}";
      style.sheet.insertRule(rule2, 0);

    }
    // fade in the new slide
    //fade(this.divLarge[this.slide], .1, 1, 20);
    this.divLarge[this.slide].style.opacity = "1";
    this.divLarge[this.slide].style.display = "block";

    var margin = (parseInt(this.divMiddle.style.width) - parseInt(this.largeSize[this.slide].displayWidth)) / 2;
    begin = 0;
    if (this.oldSlide == -1) {
      // first slide - don't move
      this.divLarge[this.slide].style.left = margin + "px";
      end = 0;
    } else if (direction == 1) {
      // next
      // move new slide from left to right
      // move to starting position
      this.divLarge[this.slide].style.left = (oldMargin - parseInt(this.largeSize[this.slide].displayWidth)) + "px";
      end = (-oldMargin + parseInt(this.largeSize[this.slide].displayWidth) + margin);
    } else {
      // prev
      // move new slide from right to left
      // move to starting position
      this.divLarge[this.slide].style.left = (oldMargin + parseInt(this.largeSize[this.oldSlide].displayWidth)) + "px";
      end = +oldMargin - (parseInt(this.largeSize[this.slide].displayWidth) + margin);
    }
    var rule = "@" + prefix + "keyframes moveNew {" +
      "0% {" + prefix + "transform: translate3d(" + begin + "px, 0, 0); }" +
      "100% {" + prefix + "transform: translate3d(" + end + "px, 0, 0); }" +
      "}";
    style.sheet.insertRule(rule, 0);

    var rule2 = "#" + this.divLarge[this.slide].id + "{" + prefix + "animation: moveNew 2s linear" + "}";
    style.sheet.insertRule(rule2, 0);
  }

  slideshow.prototype.createImage = function() {
    var img = document.createElement("img");
    var from = 100;
    var to = 300;
    var width = Math.floor(Math.random() * (to - from + 1) + from);
    var height = Math.floor(Math.random() * (to - from + 1) + from);
    img.src = "http://placehold.it/" + width + "x" + height;
    img.style.height = height;
    img.style.width = width;
    this.img.push(img);

    var div = document.createElement("div");
    div.id = "slideshow-large-" + (this.img.length - 1)
    div.style.display = "none";
    div.style.top = ((parseInt(this.divMiddle.style.height) - height) / 2) + "px";
    div.style.position = "absolute";
    div.style.width = width + "px";
    div.className = "slideshow-large";
    div.appendChild(img);

    this.divLarge.push(div);
    this.largeSize.push({
      displayWidth: width,
      displayHeight: height
    });
    this.divMiddle.appendChild(div);
  }

  return slideshow;

})();

var ss = new slideshow();

样式和HTML

<div id="next">Next Slide</div>
<div id="prev">Prev Slide</div>


#divMiddle {
  width: 600px;
  height: 600px;
  display: flex;
  position: relative;
  top: 0px;
  left: 0px;
  overflow: hidden;
}

div.slideshow-large {
  overflow: hidden;
  top: 0;
  position: absolute;
}

div.slideshow-large img {
  display: block;
}

div.slideshow-large span {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1070;
}

1 个答案:

答案 0 :(得分:0)

您应该在代码中添加animation-fill-mode: forwards,并将动画保留在结束值。对于您的代码示例,它应该是这样的:

...
var rule2 = "#" + this.divLarge[this.slide].id + "{" + prefix + "animation: moveNew 2s linear forwards" + "}";
...