滚动和.addClass();问题

时间:2011-03-09 11:39:44

标签: javascript jquery javascript-events

我正在制作一个“单页”网站,其中包含固定导航和一个文档中的大约5个不同页面。

更新的工作链接

http://www.coco-works.com/Archive/ LIVE VERSION

我在添加活动类时遇到问题。单击“保持联系”或“主页”时,不会应用该类。正如您从实时版本中看到的那样,它无法正常运行。

页面的工作原理如下; enter image description here

这是JavaScript;

$(document).ready(function() {
    $('body').click(function(event) {
        if (event.target.nodeName.toLowerCase() == 'a') {
            var op = $(event.target);
            var id = op.attr('href');
            if (id.indexOf('#') == 0) {
                $.scrollTo(id, 1000, {
                    offset: {
                        top: 75
                    },
                    axis: 'y',
                    onAfter: function() {
                        window.location.hash = id.split('#')[1];
                    }
                });
            }
            return false;
        }
    });
    $.fn.waypoint.defaults.offset = 75;
    $('.section h1.page_name').waypoint(function() {
        var id = this.id;
        var op = $('#navigation a[href = "#' + id + '"]');
        if (op.length) {
            $("#navigation a").removeClass("active");
            op.addClass('active');
        }
    });
});

我不是一个强大的程序员。我试图尽可能地编辑它,我只是卡住了。任何解决这个问题的见解都将受到高度赞赏。

仍在寻找答案,下面无法解决问题。

4 个答案:

答案 0 :(得分:3)

我不确定waypoints插件正在做什么,但我已经重构了你的代码,它对我有用。请注意,我取消了对.waypoints的调用,并将$('body')。click()处理程序更改为导航链接元素上更具体的处理程序。此处理程序将滚动到每个元素,然后在滚动完成时正确执行类的删除和添加:

$(document).ready(function()
{

    function highlightNav(navElement){
        $("#navigation a").removeClass('active');
        navElement.addClass('active');
    }

    $('#navigation a').click(function(event){
        var nav = $(this);
        var id = nav.attr('href');
        $.scrollTo(id, 1000, {
            offset: { top: -75 },
            axis: 'y',
            onAfter: function(){
                highlightNav(nav);
            }
        });
        return false;
    });

    $(window).scroll(function(){
        if($(this).scrollTop() == 0){
            highlightNav($("#navigation a[href*='home']"));
        } 
    });


    $.fn.waypoint.defaults.offset = 75;
    $('.section h1.page_name').waypoint(function() {
        var id = this.id;
        var op = $('#navigation a[href = "#' + id + '"]');
        if (op.length) {
            highlightNav(op);
        }
    });


    // Fancybox
    $("a.zoom").fancybox({
        'overlayShow'    : false,
        'transitionIn'    : 'elastic',
        'transitionOut'    : 'elastic'
    });
    $("a.outside_shade").fancybox({
        'titlePosition'        : 'outside',
        'overlayColor'        : '#000',
        'overlayOpacity'    : 0.9
    });
    $("a.inside_white").fancybox({
        'titlePosition'    : 'inside'
    });
    $("a.inside_shade").fancybox({
        'titlePosition'    : 'over'
    });

    // validation
    $("form").validate();

    // nivo slider
    $('#slider').nivoSlider();
});

在html中,我在第一个链接中添加了一个默认的活动类:

<div id="navigation">
    <ul>
        <li><a href="#home" class="active">Home</a></li>
        <li><a href="#portfolio">Portfolio</a></li>
        <li><a href="#who">Who Are We?</a></li>
        <li><a href="#service">Our Services</a></li>
        <li><a href="#features">Features</a></li>
        <li><a href="#contact">Keep in Touch</a></li>
    </ul>
</div>

此外,我在页面上注意到,在调用reset.css之前,你已经定义了你的css 。这通常是不好的做法,你可能要确保reset.css始终是第一个css文件拉进来。它似乎没有对页面造成太大影响,但有时你会得到奇怪的结果。

我在这里做了一个结果:http://jsfiddle.net/RNsFw/2/

我认为不再需要waypoints插件了。我没有改变fancybox或验证的东西,因为我不确定那些正在做什么,这不是你问题的真正部分。

我在firefox和Chrome中测试过它。如果您有疑问,请告诉我:))

答案 1 :(得分:0)

http://jsfiddle.net/vCgy8/9/

这将删除对scrollTo和waypoints插件的依赖。

 $('body').click(function(event)
         {
          if(event.target.nodeName.toLowerCase() == 'a')
          {
           var op = $(event.target);
           var id = op.attr('href');
           if(id.indexOf('#') == 0)
           {

            destination = $(id).offset().top;
            $("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination}, 1000, function() {
                var hash = id.split('#')[1];
                window.location.hash = hash;
            });

           }
           return false;
          }
         });

          $(window).scroll(function (event){
            makeActive();
         });

         function makeActive(){
            var y = $(this).scrollTop();
            if(y!==0){
                $('.page_name').each(function(){
                    var curPos = parseInt($(this).offset().top - y);
                    if(curPos <= 0){
                        var op = $('#navigation a[href = "#'+$(this).attr('id')+'"]');

                        $("#navigation a").removeClass("active");
                        op.addClass('active');
                    }
                });
            }else{
                $("#navigation a").removeClass("active");
                $("#navigation a:first").addClass('active');
            }
         }

         makeActive();

答案 2 :(得分:0)

这可能完全不相关,但我昨天遇到了类似的问题 - 在事件处理程序的回调中,jQuery操作没有在该范围内执行,但是如果你把代码扔进了类似的东西:

setTimeout(function() {
    $(selector).addClass('foo');
}, 0);
如果你在$.animate() param为$(selector).stop().animate()的情况下调用queue

它会起作用 - 与false函数(ish)类似,例如:

$(selector).stop();
$(selector).animate({ foo }, { no queue:false here });
// ^ fail

$(selector).stop();
setTimeout(function() {
    $(selector).animate({ foo }, { no queue:false here either });
}, 0);
// ^ success

与上述示例完全无关的问题虽然在行为/功能性黑客中类似,但结果却是绑定方法 - 在我的情况下我一直在使用$.bind() - 但后来我重构了这个以使用{ {1}}($.delegate()也会工作)并且按预期运行。

再次,不确定这是否相关,但我认为我会通过它以防万一。不确定这是一个错误还是我没有正确理解jQuery的一些微妙部分。

答案 3 :(得分:0)

问题不在你的js代码中,而是在你的css / page布局中。

或许问题是您使用的是waypoint插件,而您可能不想使用此特定页面。 (正如您所看到的那样,由于您使用的偏移,您在离开它时也很难再次击中“Home”航路点。)

问题是,直到您滚动到的目标元素位于浏览器窗口的最顶层时,路径点插件才会触发,相对于偏移量而言。除非您的浏览器窗口足够小以至于“保持联系”部分占据整个浏览器窗口(减去偏移量),否则“保持联系”永远不会到达顶部。

你可以在这里看到它的可视化: enter image description here

enter image description here