2012-11-22 71 views
0

我的代码,它负责在网站上放置了一些子导航这个丑陋的块,我想对我怎么能改善它的一些意见,因为即使我承认这是丑陋的地狱:)重构JS功能

也许有人有更好的主意结构,因为我不因复杂的逻辑:

positionSubItems : function() { 
     var $that = $(this), 
      $parent = $that.parents().eq(1), 
      $elements = $parent.find(' > li'), 
      $activeElements = $parent.find(' > li.active'), 
      $container = $that.parent().find(".expandedViewContainer"), 

      highestBoundary = $($elements[0]).offset().top - $($elements[0]).outerHeight(true), 
      lowestBoundary = $($elements[$elements.length - 1]).offset().top + $($elements[$elements.length - 1]).outerHeight(true), 
      containerHeight = $container.outerHeight(true), 
      elementHeight = $that.outerHeight(true), 

      returnIndex = function(selector) { 
       return $(selector).parent().index(); 
      }; 

     if($that.data().subItemsPositioned !== true) { 

      $container.css({ 
       'margin-top' : - (containerHeight/2 + (elementHeight/2)) 
      }); 

      if((lowestBoundary - highestBoundary) <= containerHeight) { 
       $container.css({ 
        'margin-top' : - ((elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0)) 
       }); 
      } 

      if($container.offset().top < highestBoundary) { 
       $container.css({ 
        'margin-top' : - ((elementHeight * 2) + (elementHeight * returnIndex($that))) 
       }); 

       if((lowestBoundary - highestBoundary) < containerHeight) { 
        $container.css({ 
         'margin-top' : - ((elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0)) 
        }); 
       } 
      } 

      if(($container.offset().top + containerHeight) >= lowestBoundary) { 
       $container.css({ 
        'margin-top' : - (containerHeight - (elementHeight * ($elements.length - returnIndex($that)))) 
       }); 

       if((lowestBoundary - highestBoundary) <= containerHeight) { 
        $container.css({ 
         'margin-top' : - ((elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0)) 
        }); 
       } 
      } 

      $that.data().subItemsPositioned = true; 
     } 

    } 

所以让我先简单介绍一下它的作用。假设我们有一个左侧垂直导航(垂直列表li)。在那些li中,我们有一个链接和另一个div,其中还包含另一个项目列表。根据一定的规则的li这么一下这个功能需要的做它的位置该子级别:

  • 有两个边界,一个上对应于最上面的“礼”项目的第一级,再加上它自己的高度,另一个较低,对应于最低的li加上它自己的高度
  • 第一个条件是始终将子容器放置在子容器中并显示在容器的右侧父母li,所以父母它显示在该容器的中间
  • 基于上述规则,如果第e导致容器的定位超过上边界,然后重新定位容器以使容器的顶部偏移与当前的上边界处于同一水平
  • 继续点击其余的项目遵循第一个规则,apply第二个,如果是这样的话,那么如果符合以下条件,则符合它:当容器底部的偏移量超过最低边界时,重新定位它以使容器的底部始终与最低边界处于同一水平
  • 经过上述所有规则和条件之后,您还必须检查容器的高度是否大于上下边界之间的高度,在这种情况下,应用第一条规则,将容器置于相同位置水平作为上限
  • 还遇到了另一种情况,如果父母很少,并且容器的高度现在再次超过边界之间高度的高度,则我们必须应用刚才提到的规则
  • 和还有另一种情况,我不会描述,因为我已经深入到细节

所以说上述,我希望有人有更好的方式做所有的逻辑,也许更清洁的方式: )

+0

@roasted〜第一个它是这样我可以去两层,找到一些特定的元素,第二个是它,所以我可以去只有一个层次:) – Roland

+0

雅对不起,我犯了一个错误 –

回答

1

没有测试,如果底层逻辑是有道理的,这是稍微容易在我看来阅读

if(!$that.data().subItemsPositioned) { 
    var offset=0; 
    var ulOuterHeight = (elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0); 
    switch(true) { 
    case (lowestBoundary - highestBoundary) <= containerHeight : 
     offset = ulOuterHeight; 
     break; 
    case $container.offset().top < highestBoundary : 
     if((lowestBoundary - highestBoundary) < containerHeight) { 
     offset = ulOuterHeight; 
     } 
     else offset = (elementHeight * 2) + (elementHeight * returnIndex($that)) 
     break; 
    case ($container.offset().top + containerHeight) >= lowestBoundary : 
     if((lowestBoundary - highestBoundary) <= containerHeight) { 
     offset = ulOuterHeight; 
     } 
     else offset = containerHeight - (elementHeight * ($elements.length - returnIndex($that))); 
     break; 
    default: offset = containerHeight/2 + (elementHeight/2); 
    } 
    $container.css({'margin-top' : - offset }); 
    $that.data().subItemsPositioned = true; 
} 
+0

@mplungian〜在这种情况下,问题是我首先需要将位置设置为居中,然后检查其他情况是否适用...或者至少这是它在我的脑海中的情况:) – Roland

1

这段代码看起来总是一样的,试着把if条件(可能放入函数):

$container.css({ 
    'margin-top' : - ((elementHeight * 2) + (elementHeight *  returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0)) 
}); 

我认为这应该是一个好的开始。寻找这是重复

1

这里的代码行是一些类的实例(不准确读你的功能是什么,只是一些重构干这个功能有点高达

这仍是某种丑陋的,但我希望它可以帮助你推到正确的方向

positionSubItems : function() { 
    var $that = $(this), 
    $parent = $that.parents().eq(1), 
    $elements = $parent.find(' > li'), 
    $activeElements = $parent.find(' > li.active'), 
    $container = $that.parent().find(".expandedViewContainer"), 

    highestBoundary = $($elements[0]).offset().top - $($elements[0]).outerHeight(true), 
    lowestBoundary = $($elements[$elements.length - 1]).offset().top + $($elements[$elements.length - 1]).outerHeight(true), 
    containerHeight = $container.outerHeight(true), 
    elementHeight = $that.outerHeight(true), 

    returnIndex = function(selector) { 
     return $(selector).parent().index(); 
    }, 

    containerCSS = function(marginTop) { 
     $container.css({ 
      'margin-top' : - marginTop 
     }); 
    }, 

    doTheMarginTop = function() { 
     containerCSS((elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0)); 
    }; 

if($that.data().subItemsPositioned !== true) { 

    containerCSS(containerHeight/2 + (elementHeight/2)); 

    if((lowestBoundary - highestBoundary) <= containerHeight) { 
     doTheMarginTop(); 
    } 

    if($container.offset().top < highestBoundary) { 
     containerCSS(((elementHeight * 2) + (elementHeight * returnIndex($that)))); 

     if((lowestBoundary - highestBoundary) < containerHeight) { 
      doTheMarginTop(); 
     } 
    } 

    if(($container.offset().top + containerHeight) >= lowestBoundary) { 
     containerCSS(containerHeight - (elementHeight * ($elements.length - returnIndex($that)))); 
     if((lowestBoundary - highestBoundary) <= containerHeight) { doTheMarginTop(); } 
    } 

    $that.data().subItemsPositioned = true; 
} 

}