【问题标题】:How to fix an element after scroll in an AngularJS webpage如何在 AngularJS 网页中滚动后修复元素
【发布时间】:2015-01-28 11:36:41
【问题描述】:

我最近在 AngularJs 中创建了一个网站。我还处于学习阶段。 我希望在页面到达顶部后修复页面上的元素。我尝试了各种 Javascript 和 Jquery 函数。但是,它们似乎不起作用。

我也尝试使用 Angular UI 的 ui-scrollfix,但它也不起作用。

我正在分享我的代码。这是一个部分页面。请教我一种方法来达到上述效果。

<div class="row pdiv">


    <div class="col-md-8 pdiv col-md-offset-2">
        <h3><b>About Us</b></h3>
        <ul class="nav nav-justified">
            <li role="presentation"><a href="" ng-click="scrollTo('weAre')">What are    we?</a></li>
            <li role="presentation"><a href="" ng-click="scrollTo('brandsAssociation')">Brands Associations</a></li>
            <li role="presentation"><a href="" ng-click="scrollTo('knowUs')">Know Us</a></li>
            <li role="presentation"><a href="" ng-click="scrollTo('motto')">Our Motto</a></li>
        </ul>
    </div>

    <div id="weAre" class="col-md-8 pdiv col-md-offset-2">
    <br>
    <h4><b>What are we?</b></h4>
    <p>Some content goes here.</p>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    </div>

    <div id="brandsAssociation" class="col-md-8 pdiv col-md-offset-2">
    <br>
    <h4><b>Brands Associations</b></h4>
    <p>Some content goes here.</p>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    </div>

    <div id="knowUs" class="col-md-8 pdiv col-md-offset-2">
    <br>
    <h4><b>Know Us</b></h4>
    <p>Some content goes here.</p>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    </div>

    <div id="motto" class="col-md-8 pdiv col-md-offset-2">
    <br>
    <h4><b>Our Motto</b></h4>
    <p>Some content goes here.</p>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    </div>

</div>


<a href="" ng-click="scrollTo('header')"><span id="toTop" class="glyphicon glyphicon-chevron-up"></span></a>

我需要在 ul 类 .nav .nav-justified 到达页面顶部后对其进行修复。

我正在使用引导程序。

这里是 javascript 依赖项。

<script src="angular/angular.min.js"></script>
<script src="angular/angular-route.js"></script>
<script src="js/jquery.js"></script>
<script src="js/bootstrap.min.js"></script>

请帮忙...

【问题讨论】:

    标签: javascript jquery html css angularjs


    【解决方案1】:

    要在滚动时将ul 固定到顶部,您可以在其上放置一个指令,检查窗口的scrollTop() 是否超过ul 元素的offset 顶部。发生这种情况时,该指令只需向将其固定到顶部的元素添加一个类。

    所以你的ul 标记看起来像这样,上面有新指令set-class-when-at-top

    <ul class="nav nav-justified" set-class-when-at-top="fix-to-top">
    

    当元素到达页面顶部时,该指令会将 CSS 类 fix-to-top 添加到元素中。指令定义如下所示:

    app.directive('setClassWhenAtTop', function ($window) {
      var $win = angular.element($window); // wrap window object as jQuery object
    
      return {
        restrict: 'A',
        link: function (scope, element, attrs) {
          var topClass = attrs.setClassWhenAtTop, // get CSS class from directive's attribute value
              offsetTop = element.offset().top; // get element's offset top relative to document
    
          $win.on('scroll', function (e) {
            if ($win.scrollTop() >= offsetTop) {
              element.addClass(topClass);
            } else {
              element.removeClass(topClass);
            }
          });
        }
      };
    });
    

    如果你想变得有点厚脸皮,你甚至可以将你的 scroll 处理程序减少到一行:

    $win.on('scroll', function (e) {
      element[($win.scrollTop() >= offsetTop) ? 'addClass' : 'removeClass'](topClass);
    });
    

    fix-to-top CSS 类将是这样的:

    .fix-to-top {
      position: fixed;
      top: 0;
    }
    

    这是fiddle

    【讨论】:

    • $animate.pin() 函数有什么作用?在 ng-animate 模块中不一样吗?
    • 谢谢伙计。你节省了我的时间。
    • 在指令的开头设置变量很尴尬。最好将它放在“链接”中,但是创建几个 $window 实例也很尴尬。这是一种方法,但我猜不是最好的。我认为使用 ng-class 和一个小功能也可以。
    • 你救了我的命。很好的解决方案。谢谢
    • 非常酷的解决方案,但它不适用于移动设备(Phonegap 混合应用程序)。有人可以提出一些建议吗? (可能是因为 $window 是基于浏览器的服务,它可能不适用于移动应用程序。如果我是正确的,那么移动设备的答案可能是什么)
    【解决方案2】:

    我开始使用 MikeJ 的最佳答案开始,但很快意识到一些缺点:

    1. 在首次解析指令后,没有考虑元素上方的内容何时动态变化
    2. 固定元素下方的内容在元素固定后向上移动,并从正常文档流中移除
    3. 如果这个元素被固定在其他东西下面(比如顶部菜单),你可能会在计算正确的位置时遇到一些麻烦;您需要在 offset top 超过 $win.scrollTop() 之前修复它,这样它就不会消失在该菜单后面,然后再修复。

    为了解决这些问题,我想出了一个修改版本:

    function setClassWhenAtTop($window) {
        var $win = angular.element($window);
    
        return {
            restrict: "A",
            link: function (scope, element, attrs) {
                var topClass = attrs.setClassWhenAtTop,
                    topPadding = parseInt(attrs.paddingWhenAtTop, 10),
                    parent = element.parent(),
                    offsetTop;
    
                $win.on("scroll", function () {
                    // dynamic page layout so have to recalculate every time;
                    // take offset of parent because after the element gets fixed
                    // it now has a different offset from the top
                    offsetTop = parent.offset().top - topPadding;
                    if ($win.scrollTop() >= offsetTop) {
                        element.addClass(topClass);
                        parent.height(element.height());
                    } else {
                        element.removeClass(topClass);
                        parent.css("height", null);
                    }
                });
            }
        };
    }
    

    这需要将您要修复的元素包装在一个空父级中,该父级仅包含要修复的元素。这是为了处理既知道元素的原始偏移量在哪里(将其放回文档流中),又要处理原始元素的高度以保持文档流原样。此外,为paddingWhenAtTop 传递一个属性,以便尽快修复它(如果需要,也可以稍后修复)。

    在 HTML 中的使用变化如下:

    <div>
      <ul class="nav nav-justified" set-class-when-at-top="fix-to-top" padding-when-at-top="50">
    </div>
    

    【讨论】:

      【解决方案3】:

      这是我尝试使其完整的 angularjs :

      JS

      .directive('setClassWhenAtTop', ['$window', function($window) {
          var $win = angular.element($window); // wrap window object as jQuery object
      
          return {
              restrict: 'A',
              link: function (scope, element, attrs)
              {
                  var topClass = attrs.setClassWhenAtTop, // get CSS class from directive's attribute value
                      topPadding = parseInt(attrs.paddingWhenAtTop, 10),
                      offsetTop = element.prop('offsetTop'); // get element's offset top relative to document
      
                  $win.on('scroll', function (e) {
                      if ($window.pageYOffset + topPadding >= offsetTop) {
                          element.addClass(topClass);
                      } else {
                          element.removeClass(topClass);
                      }
                  });
              }
          };
      }])
      

      CSS

      .fix-to-top {
          position: fixed;
          top: 55px;
          height: 50px;
          z-index: 999;
          width: 100%;
      }
      

      HTML

      <div class="navigation-bar" set-class-when-at-top="fix-to-top" padding-when-at-top="55"> 
      ...
      

      跳过 jquery 的主要更改:

      parent.offset().top => element.prop('offsetTop')
      $win.scrollTop() => $window.pageYOffset
      

      每日提示: 请不要总是给 angularjs 标题问题 jquery 答案!或者至少在你的标题或你的回答要求中清楚地表明它;-)

      【讨论】:

      • 感谢纯 Angular 方法!有一段时间没有使用 angular 后我有点困惑,为什么在其他解决方案中没有为我定义函数:D
      • 感谢您的提醒,在看到这个答案之前,我一直试图弄清楚为什么 sn-p 根本不起作用。我已经编辑了主要答案,希望能更清楚。
      • 感谢您的帮助。你拯救了生命
      • 我需要将 if ($window.pageYOffset + topPadding >= offsetTop) 更改为 if ($window.pageYOffset + topPadding > offsetTop) ,即删除相等运算符以转到 else 块以删除类并使其正常工作。
      猜你喜欢
      • 2014-01-22
      • 2019-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-12
      • 1970-01-01
      • 2013-05-02
      • 1970-01-01
      相关资源
      最近更新 更多