使用回调动画悬停效果时出现问题

时间:2016-02-18 07:04:42

标签: javascript jquery

所以当我在jQuery中使用hover事件时,我遇到了这个问题。我有两个并排的容器。我有两个悬停事件。悬停时,带有附加信息的div会向上滑动到框架中。当您将鼠标悬停时,它会向下滑动。

简单吧?当您将鼠标悬停在元素上时,它应该删除“隐藏我”类并开始向上滑动信息(动画)。当你悬停一个元素时,一旦动画完成,就应该删除“hide-me”类。当你将鼠标悬停在一个不是网格项的元素上时,这样可以正常工作。当你将一个项目悬停在另一个网格项目上时,它似乎只是将“hide-me”类添加到当前悬停的元素中。即使悬停事件还没有解决。

无论如何,这里有足够的话题是JS Fiddle上的代码:

https://jsfiddle.net/joemoe_1984/2k22yLmd/2/

这里的测试是有效的:

从图像下方/上方悬停,然后从图像下方/上方悬停

测试它是如何工作的:

从图像下方/上方悬停,然后将鼠标悬停在其他图像上

更新

只是澄清一点,因为我得到了一个答案,让我得到了我想要的效果,但并没有完全解决我所遇到的问题。我想知道为什么当从一个图像悬停到另一个图像时,完成的动画回调不能正常工作。这是最让我烦恼的部分。当您将鼠标悬停在图像上然后将其移除时,将在悬停时删除该类,然后在从悬停输出事件调用的动画完成后添加该类。这是预期的行为。当我将鼠标悬停在图像上然后悬停在另一个图像上时,您会看到不是将该类添加到第一个图像上,而是将其添加到当前悬停的图像中。它好像动画回调一旦在悬停时动画就调用了错误的回调函数。

on hover状态永远不应该添加类。此时应将其删除。在任何动画状态期间也不应添加该类。

以防链接不正常,这里是完整的html,css和javascript:

HTML

<div class="grid-container">

        <div class="grid-item">
            <a href="#" class="grid-inner">
                <div class="grid-image">
                    <img src="http://vignette3.wikia.nocookie.net/metroid/images/8/86/Samus_artwork_11.jpg/revision/latest?cb=20100516174330" alt="">
                </div>
                <div class="grid-info hide-me">
                    <div class="middle-align">
                        <h4 class="grid-title">Some title</h4>
                        <div class="grid-details">
                            This is some info about this item
                        </div>
                    </div>
                </div>
            </a>
        </div>

        <div class="grid-item">
            <a href="#" class="grid-inner">
                <div class="grid-image">
                    <img src="http://vignette3.wikia.nocookie.net/metroid/images/8/86/Samus_artwork_11.jpg/revision/latest?cb=20100516174330" alt="">
                </div>
                <div class="grid-info hide-me">
                    <div class="middle-align">
                        <h4 class="grid-title">Some title</h4>
                        <div class="grid-details">
                            This is some info about this item
                        </div>
                    </div>
                </div>
            </a>
        </div>
    </div>

CSS

.grid-item {
    width: 25%;
    float: left;
    overflow: hidden;
}

.grid-item img {
    max-width: 100%;
    height: auto;
}

.grid-inner {
    position: relative;
    display: block;
}
.grid-info {
    position: absolute;
    background: blue;
    color: white;
    width: 100%;
    height: 100%;
}

.hide-me {
    display: none;
}
.middle-align {
    position: relative;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
}

的Javascript

$(document).ready(function() {

    $('.grid-item').hover(hover_in, hover_out);

    function hover_in(e) {
        $info = $(e.currentTarget).find('.grid-info');
        target_height = $(e.currentTarget).height();
        $info.css('top', target_height).removeClass('hide-me');

        $info.stop().animate({
            'top': 0,
        }, 500, function() {
            console.log('animated up');
        });
    }

    function hover_out(e) {
        $info = $(e.currentTarget).find('.grid-info');
        target_height = $(e.currentTarget).height();

        $info.stop().animate({
            'top': target_height,
        }, 500, function() {
            console.log('animated down');
            $info.addClass('hide-me');
        });
    }
});

2 个答案:

答案 0 :(得分:1)

.show() <{1}}致电.stop()后,尝试使用.removeClass('hide-me')替换hover_in

$(document).ready(function() {

  $('.grid-item').hover(hover_in, hover_out);

  function hover_in(e) {
    $info = $(e.currentTarget).find('.grid-info');
    target_height = $(e.currentTarget).height();
    $info.css('top', target_height) //.removeClass('hide-me')    
      .stop()
      .show()
      .animate({
        'top': 0,
      }, 500, function() {
        console.log('animated up');
      });
  }

  function hover_out(e) {
    $info = $(e.currentTarget).find('.grid-info');
    target_height = $(e.currentTarget).height();

    $info.stop().animate({
      'top': target_height,
    }, 500, function() {
      console.log('animated down');
      $info.addClass('hide-me');
    });
  }
});
.grid-item {
  width: 25%;
  float: left;
  overflow: hidden;
}
.grid-item img {
  max-width: 100%;
  height: auto;
}
.grid-inner {
  position: relative;
  display: block;
}
.grid-info {
  position: absolute;
  background: blue;
  color: white;
  width: 100%;
  height: 100%;
}
.hide-me {
  display: none;
}
.middle-align {
  position: relative;
  top: 50%;
  -webkit-transform: translateY(-50%);
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

<body>

  <h1>Animation grid</h1>

  <div class="grid-container">

    <div class="grid-item">
      <a href="#" class="grid-inner">
        <div class="grid-image">
          <img src="http://vignette3.wikia.nocookie.net/metroid/images/8/86/Samus_artwork_11.jpg/revision/latest?cb=20100516174330" alt="">
        </div>
        <div class="grid-info hide-me">
          <div class="middle-align">
            <h4 class="grid-title">Some title</h4>
            <div class="grid-details">
              This is some info about this item
            </div>
          </div>
        </div>
      </a>
    </div>

    <div class="grid-item">
      <a href="#" class="grid-inner">
        <div class="grid-image">
          <img src="http://vignette3.wikia.nocookie.net/metroid/images/8/86/Samus_artwork_11.jpg/revision/latest?cb=20100516174330" alt="">
        </div>
        <div class="grid-info hide-me">
          <div class="middle-align">
            <h4 class="grid-title">Some title</h4>
            <div class="grid-details">
              This is some info about this item
            </div>
          </div>
        </div>
      </a>
    </div>
  </div>

</body>

jsfiddle https://jsfiddle.net/2k22yLmd/3/

答案 1 :(得分:0)

确定。所以我明白了。事实证明这是一个范围问题。问题源于在悬停事件范围内使用e.currentTarget(或this)。我将该实例存储到一个变量中,然后在动画序列的回调中使用它。

当前目标似乎从动画回调使用它时发生变化,从而给出意外结果。对于动画回调,我应该在动画回调函数的范围内使用实例(this),如下所示:

$info.stop().animate({
    'top': target_height,
}, 500, function() {
    console.log('animated down');
    $(this).addClass('hide-me'); // this refers to the current animated object. This is the correct one.
    $info.addClass('wrong-one'); // $info refers to the current hover event target which is the on hover item when it should be the hover off item. This is incorrect
});

你可以测试它,看看从一个图像到下一个图像现在将类hide-me添加到正确的一个,并将类wrong-one添加到当前悬停的项目,而不是我正在寻找的预期行为。

感谢大家提供答案并提供替代解决方案,但这对我来说是真正的问题。