【问题标题】:Using jQuery to set class on navigation based on active section使用 jQuery 设置基于活动部分的导航类
【发布时间】:2014-03-18 01:19:49
【问题描述】:

我有一些 javascript/jQuery 将一个“活动”类附加到我当前正在显示的 .section(然后滚动到活动类)。

我想要实现的是简单地在我的导航菜单跨度上设置一个类,基于哪个部分处于活动状态(因此显示当前的“页面”)。

实现这一目标的最佳方法是什么?我的导航嵌套在我的部分之外,我想最终得到类似于

if($('#page1').hasClass('active'){
   $('.label1').addClass('show') .siblings().removeClass('show');
}

这种导航的最佳做法是什么?显示?

编辑: 该站点的当前测试版本在这里:http://thetearoom.server105.com/indexv6.html

我知道这些很长而且有点凌乱,所以请多多包涵=)

html:

<body>
    <div class="static">

    <div id="top">

    <!--            THIS IS FOR LATER HEADER-->
    <div id="headerlogo">

    </div>
    <div id="headertext">  </div>     
    </div>
        </div>
        <ul class="vnav">
            <li><a href="#p1" onclick="$('#p1').addClass('active') .siblings().removeClass('active');">
                    <span class="label2">WELCOME</span>
            </a></li>
            <li><a href="#p2" onclick="$('#p2').addClass('active') .siblings().removeClass('active');">
                    <span class="label3">ABOUT US</span>
            </a></li>
            <li><a href="#p3" onclick="$('#p3').addClass('active') .siblings().removeClass('active');">
                    <span class="label4">AFTERNOON TEA</span>
            </a></li>
        </ul>

    <!--        FOR NOW P1 CONTAINS HEADER AND P3 CONTAINS FOOTER-->
    <div id="container">
<!--                        THESE WERE THE ENTIRE IMAGE VERSIONS OF THE OVERLAYED FLOATS-->
<!--                <div id="blur" data-0="background-position:0em 18em;" data-3000="background-position:0em -4em;"></div>
            <div id="focus" data-0="background-position:0em 0em;" data-3000="background-position:0em 10em;"></div>-->


        <div id="p1" class="section">
            <div class="content">
<!--                    floatcontent-->

                    <img src="img/focus/lhs_toppetal.png" alt="" height="75" width="165" class="overlay" id="lhs_toppetal" data-0="top:20%;" data-end="top:80%;">
                    <img src="img/focus/rhs_petal.png" alt="" height="205" width="261" class="overlay" id="rhs_petal" data-0=" bottom:-8%;" data-end="bottom:-82%;">
                    <img src="img/blur/top_petalright.png" alt="" height="56" width="125" class="overlay" id="top_petalright" data-0="bottom:36%;" data-end="bottom:95%;">
                    <img src="img/blur/top_petalleft.png" alt="" height="98" width="125" class="overlay" id="top_petalleft" data-0="top: 77%;" data-end="top:10%;">
                    <div id="title">


                    </div>
                <div class="tbb" id="tb1">
                <div class="textbox" id="welcome">
                    <h3>Welcome</h3>
                    <p>
                        Creating experiences beyond comparison...<br>
                        The Tea Room offers traditional afternoon tea, a la carte lunch,<br>
                        private events and wedding receptions. Renowned for beautiful venues
                        in historic locations, this is a world class dining experience.
                    </p>
                </div>
                </div>  
<!--                        THIS IS THE SCROLL BUTTON-->
                    <div class="next" data-0="z-index:120;" data-650="z-index:120;" data-680="z-index:-1;"><a href="#p2" onclick="$('#p2').addClass('active') .siblings().removeClass('active');"><span></span></a></div>
        </div>
        </div>

<!--            <div class="divider">Simple Divider</div>-->

        <div id="p2" class="section">

            <div class="content">
<!--                    floatcontent-->
                    <img src="img/focus/lhs_petal.png" alt="" height="205" width="261" class="overlay" id="lhs_petal" data-500="top:66%;" data-end="top:10%;">
                    <img src="img/blur/middlerightpetal.png" alt="" height="217" width="333" class="overlay" id="middlerightpetal" data-500="top: 31%;" data-end="top:5%;">
                    <img src="img/blur/middleleftpetal.png" alt="" height="163" width="368" class="overlay" id="middleleftpetal" data-100="top: -13%;" data-end="top:28%;">

                <div class="tbb">
                <div class="textbox" id="about">
                    <h3>About Us</h3>
                    <p>
                        Sed dictum quam a urna feugiat ornare. Donec vel viverra ligula. Duis 
                        eu placerat magna. Phasellus facilisis vestibulum consectetur. Suspendisse
                        vestibulum ligula orci, non feugiat ligula rhoncus non. Duis sit amet bibendum 
                        nibh. Nulla eros risus, sagittis ut lectus quis, lacinia pharetra augue. Vestibulum 
                        diam velit, consequat vel ornare at, scelerisque non nisi.<br>
                        Curabitur elementum gravida odio nec volutpat. Phasellus vel ligula eu mauris dapibus
                        onsequat non nec quam. Sed quis justo sit amet tortor varius auctor in porta orci. Quisque
                        posuere tortor, at facilisis libero. Nam nec placerat tortor, commodo cursus neque.
                        Aliquam erat volutpat. Aliquam erat volutpat. Etiam aliquet mollis consectetur.
                    </p>
                </div>
                </div>
                    <div class="next" data-680="z-index:110;" data-1300="z-index:110;" data-1350="z-index:-1;"><a href="#p3" onclick="$('#p3').addClass('active') .siblings().removeClass('active');"><span></span></a></div>
            </div>
        </div>

<!--             <div class="divider">Simple Divider</div>-->

        <div id="p3" class="section">
            <div class="content">
<!--                    FLOAT IMAGES  focus-->
                <img src="img/focus/macaroon.png" alt="" height="180" width="180" class="overlay" id="macaroon" data-1000="top: 90%;" data-end="top:18%;">
                <img src="img/focus/large_lower_cake.png" alt="" height="180" width="180" class="overlay" id="large_lower_cake" data-1000="bottom: 58%;" data-end="bottom: 28%;">
                <img src="img/focus/scroll_lower.png" alt="" height="45" width="55" class="overlay" id="scroll_lower" data-1000="bottom: 62%;" data-end="bottom: 17%;">
<!--                    FLOAT IMAGES    blur-->
                <img src="img/blur/lhs_halfscroll.png" alt="" height="356" width="210" class="overlay" id="lhs_halfscroll" data-1000="top: 95%;" data-end="top: 45%;">
                <img src="img/blur/lrhs_creamcake.png" alt="" height="115" width="118" class="overlay" id="lrhs_creamcake" data-1000="bottom: 7%;" data-end="bottom: 23%;">
                <img src="img/blur/llhs_cake.png" alt="" height="115" width="118" class="overlay" id="llhs_cake" data-1000="bottom: 78%;" data-end="bottom: 18%;">
                <div class="tbb">
                <div class="textbox" id="aftertea">
                    <h3>Afternoon Tea</h3>
                    <p>
                         Sed dictum quam a urna feugiat ornare. Donec vel viverra ligula. Duis 
                        eu placerat magna. Phasellus facilisis vestibulum consectetur. Suspendisse
                        vestibulum ligula orci, non feugiat ligula rhoncus non. Duis sit amet bibendum 
                        nibh. Nulla eros risus, sagittis ut lectus quis, lacinia pharetra augue. Vestibulum 
                        diam velit, consequat vel ornare at, scelerisque non nisi.<br>
                        Curabitur elementum gravida odio nec volutpat. Phasellus vel ligula eu mauris dapibus
                        onsequat non nec quam. Sed quis justo sit amet tortor varius auctor in porta orci. Quisque
                        posuere tortor, at facilisis libero. Nam nec placerat tortor, commodo cursus neque.
                        Aliquam erat volutpat. Aliquam erat volutpat. Etiam aliquet mollis consectetur.
                    </p>
                </div>
                </div>
<!--                    <div class="reset" ><a href="#p1"><span></span></a></div>-->
                    <div class="next" data-0="z-index:105;"><a href="#p1" onclick="$('#p1').addClass('active') .siblings().removeClass('active');"><span></span></a></div>
            </div>
        </div>



    </div>

    <footer>
    <!--            THIS IS FOR LATER FOOTER-->

        <div id="footer">

            <ul class="footlist">
                <li><a href="#">FACEBOOK</a></li>
                <li><a href="#">TWITTER</a></li>
                <li><em>&copy;</em>&nbsp;COPYRIGHT <strong>2012</strong> GRAND PACIFIC GROUP&nbsp;&nbsp;&nbsp;<em>|</em><a href="#">CAREER ENQUIRIES</a></li>
            </ul>
         </div>   

    </footer>

</body>

js:

<!--    THIS GIVES US A SMOOTH MOUSEWHEEL SCROLL-->
<!--        <script type="text/javascript" src="js/jquery-1.9.1.js"></script>-->


<!--        THIS HANDLES THE PARALLAX ANIMATIONS-->
    <script type="text/javascript" src="js/skrollr.min.js"></script>
    <script type="text/javascript" src="js/skrollr.menu.min.js"></script>
    <script type="text/javascript">
     /*Code below based on section from jsfiddle.net/NGj7E, Author unknown*/
     /*This code now selects .section class and applies active to it, scrolling to active
      * class and removing active class attr. when page scrolls. 
      * 
      * Page-by-Page works in both vertical directions and stops the default
      * wheel event from happening. Parallax will not work without js enabled.*/

         /*Set class to active on first element this serves as our indicator
          *     -.section is class to have active applied to*/
         $('.section').first().addClass('active');
         /*This handles the mousewheel event*/
             $(document).on('mousewheel DOMMouseScroll', function (e) {

        e.preventDefault();//prevent the default mousewheel scrolling
        var active = $('.section.active');
        //get the delta to determine the mousewheel scrol UP and DOWN
        var delta = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? 1 : -1;

        //if the delta value is negative, the user is scrolling down
        if (delta < 0) {
            //mousewheel down handler
            next = active.next();
            //check if the next section exist and animate the anchoring
            if (next.length) {
               /*setTimeout is here to prevent the scrolling animation

                to jump to the topmost or bottom when 
                the user scrolled very fast.*/
                var timer = setTimeout(function () {
                    /* animate the scrollTop by passing 
                    the elements offset top value */
                    $('body, html').animate({
                        scrollTop: next.offset().top
                    }, 1200, 'swing');

                    // move the indicator 'active' class
                    next.addClass('active')
                        .siblings().removeClass('active');


                    clearTimeout(timer);
                }, 420);
            }

        } else {
            //mousewheel up handler
            /*similar logic to the mousewheel down handler 
            except that we are animate the anchoring 
            to the previous sibling element*/
            prev = active.prev();

            if (prev.length) {
                var timer = setTimeout(function () {
                    $('body, html').animate({
                        scrollTop: prev.offset().top
                    }, 1200, 'swing');

                    prev.addClass('active')
                        .siblings().removeClass('active');

                    clearTimeout(timer);
                }, 420);
            }

        }

        if($('#page1').hasClass('active'){

        })
    });





    var s = skrollr.init({
    forceHeight: false,
            smoothScrolling: true,
            smoothScrollingDuration: 50

    });

    skrollr.menu.init(s, {
             easing: 'swing',
             animate: true,
             duration: function(currentTop, targetTop){
                 return Math.abs(currentTop - targetTop) * 1.4;
             }

            });

    </script>

【问题讨论】:

  • 关于其他选项,您还有更多可以显示的代码吗?我有个想法让它更具可扩展性,但我需要查看导航菜单的 HTML。
  • 嗨,我添加了我的 html 和 js,以及网站所在位置的示例。我的代码还是有点乱而且很长,所以我不想只呈现一堵文字墙。

标签: javascript jquery parallax


【解决方案1】:

好的...为了使其以可扩展的方式工作,您需要将这些内联 onclick 函数分离到外部处理程序。无论如何你都应该这样做,特别是如果使用 jQuery 因为它很容易。我不会对此进行太多详细介绍,但无论如何,请更新您的脚本:

$(function(){
    // scroll stuff

    $('.vnav').on('click','a',function(){
        var self = this,
            eqNum = (parseInt(self.href.slice(-1),10) - 1);

        $('.active')
            .removeClass('active')
            .parent()
            .find('.section')
            .eq(eqNum)
            .addClass('active');

        $('.show').removeClass('show');

        $(self).find('span').addClass('show');
    });
});

这利用了委托,因此只有一个 click 处理程序,但也减少了 DOM 遍历量。它捕获链接的href 中的“计数器值”,该链接对应于要激活的部分的ID。然后它删除当前活动项目的active 类,根据单击的链接搜索新的活动项,并将active 类添加到它。最后,它会移除活动的show span,并将其添加到点击链接内的 span。

未经测试,但应该可以工作。

编辑

让卷轴参与进来!不妨现在构建整个函数:

$(function(){
    var $navLinks = $('.vnav').find('a');

    $('.section').first().addClass('active');

    $(window).on('scroll',function(e){
        e.preventDefault();

        var $active = $('.active'),
            $show = $('.show'),
            delta = (e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? 1 : -1);

        if (delta < 0) {
            var $next = $active.next(),
                $nextLink = $next.get(0).id;

            if(next.length){
                var timer = setTimeout(function(){
                        $('body, html').animate({
                            scrollTop:$next.offset().top
                        },1200,'swing');

                    $active.removeClass('active');
                    $next.addClass('active');

                    $show.removeClass('show');
                    $navLinks.filter(function(){
                        return this.href === '#'+$nextLink
                    }).find('span').addClass('show');

                    clearTimeout(timer);
                },420);
            }
        } else {
            var $prev = $active.prev(),
                $prevLink = $prev.get(0).id;

            if(prev.length){
                var timer = setTimeout(function () {
                    $('body, html').animate({
                        scrollTop:$prev.offset().top
                    },1200,'swing');

                    $active.removeClass('active');
                    $prev.addClass('active');

                    $show.removeClass('show');
                    $navLinks.filter(function(){
                        return this.href === '#'+$prevLink
                    }).find('span').addClass('show');

                    clearTimeout(timer);
                }, 420);
            }

        }
    });

    $('.vnav').on('click','a',function(){
        var self = this,
            eqNum = (parseInt(self.href.slice(-1),10) - 1);

        $('.active')
            .removeClass('active')
            .parent()
            .find('.section')
            .eq(eqNum)
            .addClass('active');

        $('.show').removeClass('show');

        $(self).find('span').addClass('show');
    });
});

再次未经测试,但希望应该没问题。我缓存了.vnava 元素,这些元素在滚动过程中与元素过滤相结合,以匹配对应于相应链接的ID。找到此链接后,我们可以应用跨度。我还做了一些优化,并将scroll 事件绑定到窗口(这是在jQuery 中处理scroll 事件的适当方式)。

即使这不能解决所有问题,它也应该为您提供一个不错的起点。希望哈哈。

【讨论】:

  • 好的,所以这适用于单击菜单导航,但在触发鼠标滚轮事件时似乎没有效果。我将尝试嵌入它或对其进行更多修改,我会尽快回复您。虽然在链接导航上效果很好 - 完美。
  • @HulaHoof 我更新了我的答案,试图修改您的脚本以解决滚动任务。希望对您有所帮助。
  • 感谢所有的帮助 - 它并没有立即奏效(就像你说的未经测试),但有几件事我不知道你能做到!我很肯定,在我有机会梳理它之后,我将能够从中解决它
  • @HulaHoof 我注意到我在那里犯了几个错误(即,在我的$navLinks.filter() 函数中分配而不是测试),也许它适用于这些修复?无论哪种方式,很高兴我能帮上一点忙。祝你好运!
猜你喜欢
  • 2013-12-02
  • 1970-01-01
  • 2019-12-02
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 2017-12-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多