使用CSS/jQuery滚动时如何设置焦点和访问锚的样式 [英] How to style focused and visited anchors when scrolling with CSS / jQuery

查看:80
本文介绍了使用CSS/jQuery滚动时如何设置焦点和访问锚的样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个相当复杂的问题,我似乎无法回答自己.

I have a rather complex question I cant seem to answer myself.

在页面顶部,我有几个锚点可以平滑滚动至文章:

On the top of my page I have a couple anchors that smooth-scroll down to an article:

我想通过旋转箭头告诉访问者他们在页面上的位置.此箭头应指向它所代表的文章.在下一个图像中,您可以看到我要如何实现它.在这里,用户滚动了锚点1(这是具有动态高度的文章),现在正在阅读锚点2的文章:

I want to tell the visitors their location on the page by rotating the arrow. This arrow should point towards the article it is representing. In the next image you can see how I want to implement this. Here, the user has scrolled past anchor 1 (this is an article with dynamic height) and is now reading the anchor 2 article:

当访问者不在文章之外,但锚点3文章仍在滚动位置下方时,它应如下所示:

When the visitor is outside the article, but the anchor 3 article is still below the scrolled position, it should look like this:

这给我带来了两个问题:

This creates a couple of problems for me:

  1. 是否可以编写jQuery脚本,以便可以动态添加锚点?
  2. 如何在不添加额外库的情况下添加旋转动画? (我现在正在使用jquery.transit)

当前代码:(从另一篇文章中获取此信息:jsfiddle.net/m2zQE)

Current code: (got this from another post: jsfiddle.net/m2zQE)

 var topRange      = 200,  // measure from the top of the viewport to X pixels down
     edgeMargin    = 20,   // margin above the top or margin from the end of the page
     animationTime = 1200, // time in milliseconds
     contentTop = [];

$(document).ready(function(){ 

 // Stop animated scroll if the user does something
 $('html,body').bind('scroll mousedown DOMMouseScroll mousewheel keyup', function(e){
 if ( e.which > 0 || e.type == 'mousedown' || e.type == 'mousewheel' ){
  $('html,body').stop();
 }
})

 // Set up content an array of locations
 $('#navTopBar').find('a').each(function(){
  contentTop.push( $( $(this).attr('href') ).offset().top );
 })

 // Animate menu scroll to content
  $('#navTopBar').find('a').click(function(){
   var sel = this,
       newTop = Math.min( contentTop[ $('#navTopBar a').index( $(this) ) ], $(document).height() - $(window).height() ); // get content top or top position if at the document bottom
   $('html,body').stop().animate({ 'scrollTop' : newTop }, animationTime, function(){
    window.location.hash = $(sel).attr('href');
   });
   return false;
 })

 // rotate arrow
 $(window).scroll(function(){
  var winTop = $(window).scrollTop(),
      bodyHt = $(document).height(),
      vpHt = $(window).height() + edgeMargin;  // viewport height + margin
  $.each( contentTop, function(i,loc){
   if ( ( loc > winTop - edgeMargin && ( loc < winTop + topRange || ( winTop + vpHt ) >= bodyHt ) ) ){
    $('#navTopBar .anchor img')
     .removeClass('open')
     .eq(i).addClass('open');
   }
  })
 })

})

提前谢谢!

推荐答案

我认为代码看起来很熟悉;)

I thought that code looked familiar ;)

尝试类似这样的方法(演示)

Try something like this (demo)

CSS

li.selected a:after { content :' \2192' }
li.above a:after { content :' \2191' }
li.below a:after { content :' \2193' }

脚本

 var topRange = 200, // measure from the top of the viewport to X pixels down
     edgeMargin = 20, // margin above the top or margin from the end of the page
     animationTime = 1200, // time in milliseconds
     contentTop = [];

 $(document).ready(function () {
     var $menu = $('#sidemenu li'),
         updateArrows = function (sel) {
             var indx = $menu.filter('.selected').index();
             $menu
                 .filter(':lt(' + indx + ')').removeClass('below').addClass('above').end()
                 .filter(':gt(' + indx + ')').removeClass('above').addClass('below');
         };

     // Stop animated scroll if the user does something
     $('html,body').bind('scroll mousedown DOMMouseScroll mousewheel keyup', function (e) {
         if (e.which > 0 || e.type == 'mousedown' || e.type == 'mousewheel') {
             $('html,body').stop();
         }
     });

     // Set up content an array of locations
     $menu.find('a').each(function () {
         contentTop.push($($(this).attr('href')).offset().top);
     });

     // Animate menu scroll to content
     $menu.find('a').click(function () {
         var sel = this,
             newTop = Math.min(contentTop[$('#sidemenu a').index($(this))], $(document).height() - $(window).height()); // get content top or top position if at the document bottom
         $('html,body').stop().animate({
             'scrollTop': newTop
         }, animationTime, function () {
             window.location.hash = $(sel).attr('href');
             updateArrows();
         });
         return false;
     });

     // adjust side menu
     $(window).scroll(function () {
         var sel,
         winTop = $(window).scrollTop(),
             bodyHt = $(document).height(),
             vpHt = $(window).height() + edgeMargin; // viewport height + margin
         $.each(contentTop, function (i, loc) {
             if ((loc > winTop - edgeMargin && (loc < winTop + topRange || (winTop + vpHt) >= bodyHt))) {
                 $menu.removeClass('selected')
                     .eq(i).removeClass('above below').addClass('selected');
             } else {
                 updateArrows();
             }
         });
     });

     updateArrows();

 });

如果您有兴趣,我实际上将该代码转换为名为 visualNav ;它不包括这些更改-将类添加到&以上的链接下方的所选内容,但在回调函数中添加起来应该相对容易.

In case you're interested, I actually turned that code into a plugin called visualNav; it doesn't include these changes - adding classes to links above & below the selected, but it should be relatively easy to add in the callback functions.

这篇关于使用CSS/jQuery滚动时如何设置焦点和访问锚的样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆