jquery - 使用 CSS/jQuery 滚动时如何设置焦点和访问 anchor 的样式

标签 jquery css scroll anchor

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

在我的页面顶部,我有几个 anchor 可以平滑向下滚动到一篇文章:

enter image description here

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

enter image description here

当访问者在文章外面,但anchor 3文章还在滚动位置下方时,应该是这样的:

enter image description here

这给我带来了一些问题:

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

当前代码:(从另一篇文章中获取: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');
   }
  })
 })

})

提前致谢!

最佳答案

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

尝试这样的事情(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 的插件。 ;它不包括这些更改 - 将类添加到所选链接上方和下方的链接,但在回调函数中添加应该相对容易。

关于jquery - 使用 CSS/jQuery 滚动时如何设置焦点和访问 anchor 的样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25711004/

相关文章:

javascript - 如何在初始化后禁用 Flickity slider 的自动播放?

css - 为绝对定位且高度为 : 100vh 的 div 提供边距底部

css - 如何自定义表响应实现?

javascript - 如何使用用户控制的切换(启用/禁用)在 iOS 设备(iPad、iPhone、Mac)上禁用滚动/滚动

id 为 number 的 jQuery li 不会添加 addClass

javascript - 如何在鼠标移出 div 时禁用 javascript?

javascript - DIV 意外改变形状

html - 使用符号名称调用类

jquery - ScrollTop() 不工作

jquery - 滚动时更改标题的不透明度?