Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Twitter bootstrap 如何以正确的方式在angular.js中实现scrollspy?_Twitter Bootstrap_Jquery Plugins_Angularjs - Fatal编程技术网

Twitter bootstrap 如何以正确的方式在angular.js中实现scrollspy?

Twitter bootstrap 如何以正确的方式在angular.js中实现scrollspy?,twitter-bootstrap,jquery-plugins,angularjs,Twitter Bootstrap,Jquery Plugins,Angularjs,有人对在angular应用程序中实现scrollspy的最佳方式有什么想法吗?我一开始是用的,但我正在努力找到一个好地方来初始化(更重要的是在DOM更改后刷新)插件 基本上,我的控制器在加载数据时执行异步请求,在请求返回之前无法完全呈现DOM。然后,当DOM完全呈现时,需要刷新scrollspy插件。现在,我让我的控制器在收到所需数据后在其作用域上广播一个事件,并且我有一个指令拾取该事件。我真的不喜欢这个解决方案,原因有二 只是感觉有点不舒服 当我在收到此事件后刷新scrollspy插件时,仍然

有人对在angular应用程序中实现scrollspy的最佳方式有什么想法吗?我一开始是用的,但我正在努力找到一个好地方来初始化(更重要的是在DOM更改后刷新)插件

基本上,我的控制器在加载数据时执行异步请求,在请求返回之前无法完全呈现DOM。然后,当DOM完全呈现时,需要刷新scrollspy插件。现在,我让我的控制器在收到所需数据后在其作用域上广播一个事件,并且我有一个指令拾取该事件。我真的不喜欢这个解决方案,原因有二

  • 只是感觉有点不舒服

  • 当我在收到此事件后刷新scrollspy插件时,仍然太早,因为DOM直到周期的晚些时候才更新。我尝试了evalAsync,但最后我不得不使用超时,只希望DOM渲染足够快

  • 我查看了的源代码,从零开始实现它似乎相当简单。我遇到的问题是,当我试图为它创建一个指令时,我似乎无法从link函数中收到的元素订阅滚动事件


    有没有人找到一个很好的解决办法,或者有没有人有什么建议?我根本不想使用引导程序实现,目前我在引导程序上拥有的唯一dep是我刚刚添加的scrollspy插件。

    在AngularUI中使用scrollspy存在一些挑战(可能是AngularUI到2013年8月还没有包括scrollspy的原因)

    在对DOM内容进行任何更改时,必须刷新scrollspy

    这可以通过$监视元素并设置scrollspy('refresh')调用的超时来完成

    如果希望能够使用导航元素导航可滚动区域,还需要覆盖导航元素的默认行为

    这可以通过在锚元素上使用preventDefault来防止导航,并通过在ng click上附加scrollTo功能来实现


    我在Plunker上抛出了一个工作示例:

    Alexander Hill发表了一篇文章,描述了Bootstrap的ScrollSpy的AngularJS实现:

    我已经将他的CoffeeScript代码翻译成JavaScript,修复了一些bug,添加了一些安全检查和一个额外的功能。代码如下:

    app.directive('scrollSpy', function ($window) {
      return {
        restrict: 'A',
        controller: function ($scope) {
          $scope.spies = [];
          this.addSpy = function (spyObj) {
            $scope.spies.push(spyObj);
          };
        },
        link: function (scope, elem, attrs) {
          var spyElems;
          spyElems = [];
    
          scope.$watch('spies', function (spies) {
            var spy, _i, _len, _results;
            _results = [];
    
            for (_i = 0, _len = spies.length; _i < _len; _i++) {
              spy = spies[_i];
    
              if (spyElems[spy.id] == null) {
                _results.push(spyElems[spy.id] = elem.find('#' + spy.id));
              }
            }
            return _results;
          });
    
          $($window).scroll(function () {
            var highlightSpy, pos, spy, _i, _len, _ref;
            highlightSpy = null;
            _ref = scope.spies;
    
            // cycle through `spy` elements to find which to highlight
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
              spy = _ref[_i];
              spy.out();
    
              // catch case where a `spy` does not have an associated `id` anchor
              if (spyElems[spy.id].offset() === undefined) {
                continue;
              }
    
              if ((pos = spyElems[spy.id].offset().top) - $window.scrollY <= 0) {
                // the window has been scrolled past the top of a spy element
                spy.pos = pos;
    
                if (highlightSpy == null) {
                  highlightSpy = spy;
                }
                if (highlightSpy.pos < spy.pos) {
                  highlightSpy = spy;
                }
              }
            }
    
            // select the last `spy` if the scrollbar is at the bottom of the page
            if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
              spy.pos = pos;
              highlightSpy = spy;
            }        
    
            return highlightSpy != null ? highlightSpy["in"]() : void 0;
          });
        }
      };
    });
    
    app.directive('spy', function ($location, $anchorScroll) {
      return {
        restrict: "A",
        require: "^scrollSpy",
        link: function(scope, elem, attrs, affix) {
          elem.click(function () {
            $location.hash(attrs.spy);
            $anchorScroll();
          });
    
          affix.addSpy({
            id: attrs.spy,
            in: function() {
              elem.addClass('active');
            },
            out: function() {
              elem.removeClass('active');
            }
          });
        }
      };
    });
    
    应用程序指令('scrollSpy',函数($window){ 返回{ 限制:“A”, 控制器:功能($scope){ $scope.spies=[]; this.addSpy=函数(spyObj){ $scope.spies.push(间谍北京); }; }, 链接:功能(范围、要素、属性){ var spyElems; spyElems=[]; 范围:$watch('spies',函数(spies){ var spy,_i,_len,_结果; _结果=[]; 对于(_i=0,_len=spies.length;_i<_len;_i++){ 间谍; if(spyElems[spy.id]==null){ _results.push(spyElems[spy.id]=elem.find('#'+spy.id)); } } 返回结果; }); $($窗口)。滚动(函数(){ 变量highlightSpy,位置,spy,_i,_len,_ref; highlightSpy=null; _ref=scope.spies; //循环浏览“spy”元素,找出要突出显示的元素 对于(_i=0,_len=_ref.length;_i<_len;_i++){ 间谍=_ref[_i]; spy.out(); //“间谍”没有关联的“id”锚的捕获案例 if(spyElems[spy.id].offset()==未定义){ 继续; } if((pos=spyElems[spy.id].offset().top)-$window.scrollY=$(document.height()){ spy.pos=pos; highlightSpy=间谍; } return highlightSpy!=null?highlightSpy[“in”]():void 0; }); } }; }); 应用指令('spy',函数($location,$anchorScroll){ 返回{ 限制:“A”, 需要“^scrollSpy”, 链接:功能(范围、元素、属性、词缀){ 元素单击(函数(){ $location.hash(attrs.spy); $anchorScroll(); }); 添加间谍({ id:attrs.spy, in:function(){ 元素addClass(“活动”); }, 输出:函数(){ 元素移除类(“活动”); } }); } }; }); Alexander博客文章中的HTML片段,展示了如何实现该指令:

    <div class="row" scroll-spy>
      <div class="col-md-3 sidebar">
        <ul>
            <li spy="overview">Overview</li>
            <li spy="main">Main Content</li>
            <li spy="summary">Summary</li>
            <li spy="links">Other Links</li>
        </ul>
      </div>
      <div class="col-md-9 content">
        <h3 id="overview">Overview</h3>
        <!-- overview goes here -->
        <h3 id="main">Main Body</h3>
        <!-- main content goes here -->
        <h3 id="summary">Summary</h3>
        <!-- summary goes here -->
        <h3 id="links">Other Links</h3>
        <!-- other links go here -->
      </div>
    </div>
    
    
    
    • 概述
    • 主要内容
    • 总结
    • 其他链接
    概述 主体 总结 其他链接
    我在github上找到了一个项目,它可以添加scrollspy、动画scrollTo和scroll事件

    在这里您可以查看,这是

    您可以使用bower来安装它

    $ bower install angular-scroll
    

    我使用的是原始引导的scrollspy。导航链接的href就像页面没有Anuglar的ngRoute一样。然后使用选项
    重新加载为该页面设置ngRoute搜索:false
    对于我使用的滚动,角度内置支持-如果url看起来像
    http://host/#/path#anchor
    将加载指定“/path”的页面,并滚动到指定的“锚定”

    你看不到这一点,因为没有重新加载搜索:每次加载false页面时,滚动锚点中指定的id为like的元素时,都会加载false页面,但尚未呈现。为了解决初始页面加载和呈现后初始滚动到锚点的问题,编写了大量代码

    我的解决方案的最后一个元素是编写我自己的指令,放置在每个导航链接上-它停止单击传播,防止默认操作,然后设置页面锚定以符合角度要求。例如,如果页面URL为
    http://host/#/path