2

请不要推荐 JQUERY - 我做这个练习是为了学习。

我已经实现了一个 JavaScript,它使用 10 秒的设定间隔在计时器上旋转图像 (_elementSlideChange)。我还为此添加了幻灯片功能,即 7 毫秒 (_slideImage)。

图像在页面加载时每 10 秒自动旋转一次,我还提供了下一个和上一个按钮,允许用户手动更改图像。

_elementSlideChange: function () {
  var myString;
  var myText;
  for (var i = 0; i < this._imgArray.length; i++) {
    var imageArr = "url(" + this._imgArray[i].src + ")";
    var imageBg = this._imageHolder.style.background + "";
    if (imageArr == imageBg) {
      if (i == (this._imgArray.length - 1)) {
        myString = "url(" + this._imgArray[0].src + ")";
        myText = this._infoArray[0];
      } else {
        myString = "url(" + this._imgArray[(i + 1)].src + ")";
        myText = this._infoArray[i + 1];
      }
    }
  }
  this._imageNextSlide.style.background = myString;
  this._imageNextSlide.style.background);
  this._infoElement.innerHTML = myText;
  this._myTimer = setInterval(MyProject.Utils.createDelegate(this._slideImage, this),  7);
},
_slideImage: function () {
  if (parseInt(this._imageHolder.style.width) >= 0 && parseInt(this._imageNextSlide.style.width) <= 450) {
    this._imageHolder.style.backgroundPosition = "right";
    this._imageHolder.style.width = (parseInt(this._imageHolder.style.width) - 1) + 'px';
    console.log(this._imageNextSlide.style.background);
    this._imageNextSlide.style.width = (parseInt(this._imageNextSlide.style.width) + 1) + 'px';
  } else {
    console.log("reached 0px");
    if (parseInt(this._imageHolder.style.width) == 0) {
      this._imageHolder.style.background = this._imageNextSlide.style.background;
      this._imageHolder.style.width = 450 + 'px';
      this._imageHolder === this._imageNextSlide;
      this._imageHolder.className = "orginalImage";
      this._imageNextSlide.style.width = 0 + "px";
      this._imageNextSlide = this._dummyImageNextSlide;
      this._imagesElement.appendChild(this._imageHolder);
      this._imagesElement.appendChild(this._imageNextSlide);
      clearInterval(this._myTimer);
    }
    clearInterval(this._myTimer);
    clearInterval(this._elementSlideChange);
  }
}

因此,当用户单击“下一步”箭头按钮时,会触发“单击”的事件侦听器。这将为当前显示的图像创建一个 div,并创建一个新的 div,其中将包含下一个图像。图像滑动和旋转正常工作(无论是onLoad还是onClick)。我遇到的问题是,如果我单击下一步按钮,当新的 div 图像滑入到位时,它会导致它陷入无限循环,因此与要显示的图像相同的 div 不断滑入,你越多单击下一步按钮,图像开始旋转的速度越快。

我已经尝试为图像旋转和滑块设置一个明确的间隔,但我确实理解我的代码是错误的,这会导致滑动图像的无限循环。而且我知道我即将完成功能。

谁能告诉我哪里出错了?还是我应该尝试以另一种方式实现滑动 DIV?

再次请不要推荐 jQuery。

并提前感谢您的帮助。

库什

4

3 回答 3

0

似乎您想取消幻灯片上的动画(也许在下一张幻灯片动画时让它淡出,突然取消其动画或让它完成并忽略按钮单击)

我个人通常做的是检查动画状态(是的,我使用 jquery,但您应该能够以相同的方式测试用于动画的 CSS 或定位值)您甚至可以添加“活动”动画期间的类或数据类型,以使测试更容易。全局标志也有效。如果有动画,请忽略该按钮。(对于我的工作......取决于你的意图)

就像我说的,问题可能出在按钮行为上,而不是动画例程上。查看您如何通过单击按钮调用它以及您的预期结果将是有用的。

于 2013-01-03T17:27:25.683 回答
0

为了解决这个问题,我确实重写了整个代码,其中我有一个下一个和上一个按钮事件侦听器。

myProject.Utils.addHandler(this._nextImageElement, "click", myProject.Utils.createDelegate(this._changeImage, this));

两个按钮都将调用相同的功能:

_changeImage: function (e)

在此函数中,我检查该函数是否为过渡(更改图像),我声明一个布尔值 var forward = e.target == this._nextImageElement;

然后检查以查看当前索引是否前进?加 1 否则减 1

this._currentImageIndex += forward ? 1 : -1;

如果它在 Array 的末尾并且 forward 为真,则将 this._currentImageIndex 分配为重置为 0 或 Array.length - 如果它是反向的,则为 1

然后调用另一个给“div”滑动效果的函数。在这种情况下调用它this._transitionImage(forward);

在此函数中,将 this._inTranstion 设置为 true。(因为在这种情况下 div 是滑动的)。

以下代码解决了我遇到的问题。

this._slideImageElement.style.backgroundImage = "url(\"" + this._imgArray[this._currentImageIndex].src + "\")";

this._slideImageElement.style.backgroundPosition = forward ? "left" : "right";        
this._slideImageElement.style.left = forward ? "auto" : "0px";
this._slideImageElement.style.right = forward ? "0px" : "auto";

上面的代码非常重要,因为对象是将当前可见“div”的“sliding in div”向左或向右放置给用户,这主要取决于forward变量是true还是false。

var i = 0;

然后开始过渡

setInterval( function() {
    this._currentImageElement.style.backgroundPosition = (forward ? -1 : 1) * (i + 1) + "px";
       this._slideImageElement.style.width = (i + 1) + "px";

请注意,当我们乘以 -1 或 +1 时,如果它的前向将确定 bgPosition 是否会向左移动,例如,如果用户单击 NEXT BUTTON,Forward = true 所以我们要做的第一件事就是设置

this._slideImageElement.style.backgroundPosition = "left"

然后

this._slideImageElement.style.left = "auto"
this._slideImageElement.style.right = "0px"

这意味着当滑动图像在其背景位置移动时为 LEFT 但 div 放置在 RIGHT 到 0px; 然后 this._currentImageElement.style.backgroundPosition = -1 * (i + 1) 将 currentImageElement 的位置向左移动 1px

增加slideImage 的宽度,在这种情况下,它位于当前 div 的右侧,并且随着当前 div 向左移动,滑动图像开始从右侧出现。(默认情况下,将 slideImageElement 的宽度设置为 0px,以便 div 存在但对用户不可见)。这使它具有向前移动来自右侧的新图像的滑动效果。

this._slideImageElement.style.width = (i + 1) + "px";

然后声明它在它是图像宽度时停止。在这种情况下,它将是 500px。 if ((i = i + 2) == 500) { 在这个 if 语句中,重置 currentImageElement 背景和背景位置“右”或“左”并不重要,只要它已被重置。

清除间隔再次将过渡设置为false然后为函数changeImage调用一个setTimeout,它将一直持续到幻灯片完成。

下面显示了重置代码,因为这对于防止重复相同的图像非常重要(这解决了我的整个问题)

// set the current image to the "new" current image and reset it's background position
this._currentImageElement.style.backgroundImage = "url(\"" + this._imgArray[this._currentImageIndex].src + "\")";
this._currentImageElement.style.backgroundPosition = "right";

// reset the slide image width
this._slideImageElement.style.width = "0px";

// clear the transition interval and mark as not in transition
clearInterval(this._transitionInterval);
                this._inTransition = false;

// setup the next image timer
this._nextImageTimeout = setTimeout(myProject.Utils.createDelegate(this._changeImage, this), 2500);

}

我提供了详尽的细节,因为这样更容易理解问题的逻辑,即使您没有遇到同样的问题,这也可以帮助您找出任何问题。

我无法提供 JSfiddle,因为我使用 Javascript 创建了我的 CSS,有不同的方法可以做到这一点,但我想了解正向和反向背后的逻辑,并拥有一个不断前进的计时器。

于 2013-01-04T11:26:09.343 回答
-2

CSS3 过渡怎么样?

transition: all 1s ease 0.5s;

JS Fiddle 上的简单示例

这会处理动画,因此您只需要使用 JavaScript 设置预期的目的地,即

this.style.left = '100px';

或者

this.style.top = '30px';

并且 CSS3 过渡将平滑地滑动元素。

跨浏览器注意!

对于某些浏览器,该transition属性可能需要供应商前缀,我使用的是最新的生产 Firefox,而您不需要-moz。Opera 也是如此,不需要“-o”。Internet Explorer 10 不需要前缀。您可能需要-webkit用于 Safari / Chrome,但无需先进行测试。

于 2013-01-03T11:55:46.163 回答