2

有没有更好的方法来减少代码重复?

也许以某种方式循环“pagesTop”数组?

以下函数在 windows 滚动事件上初始化。

谢谢。

function redrawSideNav() {
    var pagesTop = new Array();
    $('.page').each(function(index, elem){
        pagesTop[index] = $(this);
    });

    $('.menu, .page').find('a').removeClass('active');
    if ( $(document).scrollTop() >= pagesTop[0].offset().top && $(document).scrollTop() < pagesTop[1].offset().top) {
        var target = '#' + pagesTop[0].attr('id');
        $('[href^="'+target+'"]').addClass('active');
    } else if ( $(document).scrollTop() >= pagesTop[1].offset().top && $(document).scrollTop() < pagesTop[2].offset().top) {
        var target = '#' + pagesTop[1].attr('id');
        $('[href^="'+target+'"]').addClass('active');
    } else if ( $(document).scrollTop() >= pagesTop[2].offset().top && $(document).scrollTop() < pagesTop[3].offset().top) {
        var target = '#' + pagesTop[2].attr('id');
        $('[href^="'+target+'"]').addClass('active');
    }  else if ( $(document).scrollTop() >= pagesTop[3].offset().top && $(document).scrollTop() < pagesTop[4].offset().top) {
        var target = '#' + pagesTop[3].attr('id');
        $('[href^="'+target+'"]').addClass('active');
    }   else if ( $(document).scrollTop() >= pagesTop[4].offset().top) {
        var target = '#' + pagesTop[4].attr('id');
        $('[href^="'+target+'"]').addClass('active');
    } 
}
4

3 回答 3

1

一步一步做:

首先,我将创建一个变量$(document).scrollTop()并替换if语句中的代码:

var scrollTop = $(document).scrollTop();
var targetIndex = null;

$('.menu, .page').find('a').removeClass('active');
if ( scrollTop >= pagesTop[0].offset().top && scrollTop < pagesTop[1].offset().top) {
    targetIndex = 0
} else if ( scrollTop  >= pagesTop[1].offset().top && scrollTop < pagesTop[2].offset().top) {
    targetIndex = 1;
} else if ( scrollTop  >= pagesTop[2].offset().top && scrollTop < pagesTop[3].offset().top) {
    targetIndex = 2;
}  else if ( scrollTop  >= pagesTop[3].offset().top && scrollTop < pagesTop[4].offset().top) {
    targetIndex = 3;
}   else if ( scrollTop  >= pagesTop[4].offset().top) {
    targetIndex = 4;
} 

var target = '#' + pagesTop[targetIndex].attr('id'); 
$('[href^="'+target+'"]').addClass('active');

之后,如果不使用else if级联,我将开始构建循环:

var scrollTop = $(document).scrollTop();
var targetIndex = null;
for (var i = 0; i < 4 && !targetindex; i++) {
    if (scrollTop >= pagesTop[i].offset().top && scrollTop < pagesTop[i + 1].offset().top) {
         targetIndex = i;
    }
}
targetIndex = targetIndex || 4;
var target = '#' + pagesTop[targetIndex].attr('id'); 
$('[href^="'+target+'"]').addClass('active');

(未经测试..也许我犯了一些索引/语法错误..)

于 2013-10-20T15:42:27.817 回答
1

下面的代码适用于动态大小的数组:

var scrollTop = $(document).scrollTop();
for (var i=0;i<pagesTop.length ;i++) {
    tempCond = pagesTop[i+1] ? (scrollTop <= pagesTop[i+1].offset().top) : true;
    if(scrollTop >= pagesTop[i].offset().top && tempCond ) {
       var target = '#' + pagesTop[i].attr('id');
       $('[href^="'+target+'"]').addClass('active');    
       break;
    }
}   

与武士答案的区别:
我不是在数组中添加一个虚构项目以保证循环至少执行一次并且 if 语句的第二个条件始终为真,而是在循环内部检查当前元素是否是最后一项数组:如果是 ,则直接将if语句中的第二个条件设置为true,否则将条件设置为scrollTop <= pagesTop[i+1].offset().top

于 2013-10-20T15:47:01.060 回答
1

好吧,似乎下面的代码中只有数字发生了变化,因此您可以使用带有 break 语句的 for 循环。当 break get 被触发时,for 循环的其余部分将不会被执行。最后一个else if(...)是相同的,但没有最后一个条件。我们可以通过向 pagesTop 附加一个虚拟元素来伪造这一点,这使得最后一个条件始终为真。

var a = {
    offset: function() {
        return {'top': 9999999999999};
    }
};
pagesTop.push( a );

for( var i = 0; i < pagesTop.length-1; i++ ) {
    if ( $(document).scrollTop() >= pagesTop[i].offset().top && $(document).scrollTop() < pagesTop[i+1].offset().top) {
        var target = '#' + pagesTop[i].attr('id');
        $('[href^="'+target+'"]').addClass('active');
        break;
    }
}
于 2013-10-20T15:50:04.637 回答