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