从当前的LI开始循环前一个和下一个LI

时间:2016-09-13 17:08:36

标签: javascript jquery html css css3

我目前正在玩menu animation。我实现了预期的结果,但它没有进行优化,我无法创建一个函数来循环遍历元素并应用正确的效果。

我基本上做的是在LI徘徊之前和之前经历所有LI,并根据他们的位置减少/淡化元素。所以LI越远离悬浮的那个,它越小越透明。

我的解决方案显然不灵活,因为如果我添加/删除LI,我需要再次运行所有值。

我很想知道如何简化它。

代码非常简单。

$(document).ready(function(){
  $("ul li").on("mouseover", function(){
    $("ul li").removeClass("current");
    var liLength = $("ul li").length;
    $(this).css({
        "width": "42",
        "opacity": "1"
      }).prevAll().eq(0).css({
        "width": "35",
        "opacity": "0.8333333334"
      }).prevAll().eq(0).css({
        "width": "28",
        "opacity": "0.6666666667"           
      }).prevAll().eq(0).css({
        "width": "21",
        "opacity": "0.5"
     }).prevAll().eq(0).css({
        "width": "14",
        "opacity": "0.3333333333"
      }).prevAll().eq(0).css({
        "width": "7",
        "opacity": "0.16666666667"
      });

    $(this).css({
        "width": "42",
        "opacity": "1"
      }).nextAll().eq(0).css({
        "width": "35",
        "opacity": "0.8333333334"
      }).nextAll().eq(0).css({
        "width": "28",
        "opacity": "0.6666666667"           
      }).nextAll().eq(0).css({
        "width": "21",
        "opacity": "0.5"
     }).nextAll().eq(0).css({
        "width": "14",
        "opacity": "0.3333333333"
      }).nextAll().eq(0).css({
        "width": "7",
        "opacity": "0.16666666667"
      });

  $("ul li").on("mouseout", function(){
    $("ul li").removeClass("current").css({
      "width": "21",
      "opacity": "1"
    });
  });
  });
});
html, body, ul{
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

.container{
  height: 100%;
  display: flex;
  -webkit-align-items: center;
  -webkit-box-align: center;
  align-items: center; 
}

ul{
 display: block;
 position: relative;
 height: auto;
}

ul li{
 list-style:none;
 background: #232323;
 border-top: 10px solid #fff;
 border-bottom: 10px solid #fff;
 border-right: 10px solid #fff;
 height: 10px;
 width: 21px;
 translate3d(0,0,0);
 -webkit-transition: all 200ms linear;
 transition:all 200ms linear;
}

ul li.current{
 background: blue;
}

.exp{
 position: fixed;
 top: 0;
 right: 0;
 background: grey;
 width: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

关键要素:

较大的元素应为42px宽,不透明度:1 较小的元素应为7px宽,不透明度:0.2

大小应该减少如下:(42 - 7)/ x-elements *元素的索引与其悬停元素的位置相比。

不透明度应减少如下:(1 - 0.2)/ x-elements *元素的索引与其悬停元素的位置相比。

原型:Codepen

非常感谢!

2 个答案:

答案 0 :(得分:2)

您可以遍历每个元素集合并使用index作为指标;尝试这样的事情:

$(this).css({"width": "42","opacity":"1"})
       .prevAll().each(function(index){
           $(this).css({
              "width": ((42-7)/(index+1))+"px",
               "opacity": ((1-0.2)/(index+1))
            })
       })

Codepen Demo

答案 1 :(得分:2)

我和DaniP做过类似的事情。虽然他的代码更加优化。由于我花了很多时间把它放在一起,所以我在这里发帖更多:)

就像我说的那样,看看Dani的codepen,它的代码要少得多,但是如果你需要用额外的变量来扩展这些函数,请看看我的小提琴:

https://jsfiddle.net/uyazymmu/2/

代码非常简单,需要经过几个基本步骤:

  1. 找到悬停元素的位置
  2. 计算li的数量
  3. 设置悬停元素的初始CSS
  4. 遍历所有其他元素,并根据与初始元素的相对距离调整CSS。
  5. 以下是代码:

    $(document).ready(function() {
    
      $('li').mouseenter(function() {
        var li_index = $(this).index() + 1; // mark the position of the li
        var li_total = $('li').length; //total li's
    
        $(this).css({ //initial CSS
          'width': '42px',
          'opacity': '1'
        });
    
        $(this).prevAll().each(function() { //loop through all previous li's
          var prev_index = $(this).index() + 1;
          var distance = li_index - prev_index;
          var opacity = 1 - (0.2 * distance);
          var width = 42 - (7 * distance);
          $(this).css({
            'width': width + 'px',
            'opacity': opacity
          });
        });
    
        $(this).nextAll().each(function() { // loop through all the next li's
          var next_index = $(this).index() + 1;
          var distance = next_index - li_index;
          var opacity = 1 - (0.2 * distance);
          var width = 42 - (7 * distance);
          $(this).css({
            'width': width + 'px',
            'opacity': opacity
          });
        });
      });
    
      $('li').mouseleave(function() {
        $('li').each(function() {
          $(this).css({ //reset everything
            'width': '21px',
            'opacity': '1'
          });
        });
      });
    
    });
    html,
    body,
    ul {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
    }
    
    .container {
      height: 100%;
      display: flex;
      -webkit-align-items: center;
      -webkit-box-align: center;
      align-items: center;
    }
    
    ul {
      display: block;
      position: relative;
      height: auto;
    }
    
    ul li {
      list-style: none;
      background: #232323;
      border-top: 20px solid #fff;
      border-bottom: 20px solid #fff;
      border-right: 40px solid #fff;
      height: 2px;
      width: 21px;
      translate3d(0, 0, 0);
      -webkit-transition: all 200ms linear;
      transition: all 200ms linear;
    }
    
    ul li.current {
      background: blue;
    }
    
    .exp {
      position: fixed;
      top: 0;
      right: 0;
      background: grey;
      width: 20px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="container">
      <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
      </ul>
    </div>