我是AngularJS的新手。我正在使用AngularJS 1.2.5和Bootstrap 3.0。我想在我的应用程序中包含ScrollSpy。但是,我遇到了一些挑战。我正在尝试合并找到的here代码。目前,我的代码如下所示:
的index.html
<div class="row" scroll-spy>
<div class="col-md-3 sidebar">
<ul style="position:fixed;" class="nav nav-pills nav-stacked">
<li class="active" spy="overview"><a href="#overview">Overview</a></li>
<li spy="main"><a href="#main">Main Content</a></li>
<li spy="summary"><a href="#summary">Summary</a></li>
<li spy="links"><a href="#links">Other Links</a></li>
</ul>
</div>
<div class="col-md-9 content">
<h3 id="overview">Overview</h3>
Lorem Ipsum Text goes here...
<h3 id="main">Main Body</h3>
Lorem Ipsum Text goes here...
<h3 id="summary">Summary</h3>
Lorem Ipsum text goes here...
<h3 id="links">Other Links</h3>
</div>
</div>
index.html.js
angular.module('td.controls.scrollSpy', [])
.directive('spy', function ($location) {
return {
restrict: 'A',
require: '^scrollSpy',
link: function (scope, elem, attrs, scrollSpy) {
var _ref;
if ((_ref = attrs.spyClass) == null) {
attrs.spyClass = 'current';
}
elem.click(function () {
return scope.$apply(function () {
return $location.hash(attrs.spy);
});
});
return scrollSpy.addSpy({
id: attrs.spy,
'in': function () {
return elem.addClass(attrs.spyClass);
},
out: function () {
return elem.removeClass(attrs.spyClass);
}
});
}
};
})
.directive('scrollSpy', function ($location) {
return {
restrict: 'A',
controller: function ($scope) {
$scope.spies = [];
return this.addSpy = function (spyObj) {
return $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));
} else {
_results.push(void 0);
}
}
return _results;
});
return $($window).scroll(function () {
var highlightSpy, pos, spy, _i, _len, _ref;
highlightSpy = null;
_ref = scope.spies;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
spy = _ref[_i];
spy.out();
spyElems[spy.id] = spyElems[spy.id].length === 0 ? elem.find('#' + spy.id) : spyElems[spy.id];
if (spyElems[spy.id].length !== 0) {
if ((pos = spyElems[spy.id].offset().top) - $window.scrollY <= 0) {
spy.pos = pos;
if (highlightSpy == null) {
highlightSpy = spy;
}
if (highlightSpy.pos < spy.pos) {
highlightSpy = spy;
}
}
}
}
return highlightSpy != null ? highlightSpy['in']() : void 0;
});
}
};
})
;
当我在浏览器中运行时,我遇到了几个错误。当我最初运行它时,我在浏览器控制台中看到以下错误:
TypeError: Object function (spyObj) { return $scope.spies.push(spyObj); } has no method 'addSpy'
ReferenceError: $window is not defined
我无法弄清楚a)为什么我会收到这些错误或b)如何让这个基本的例子工作。我真的很喜欢使用带有AngularJS的scrollspy的方法。这是我见过的最干净的实现。出于这个原因,我想知道如何使这个工作。
答案 0 :(得分:2)
我最近也遇到过亚历山大的解决方案,并经历了翻译过程。
要回答您的直接问题:您需要将$window
导入scrollSpy
指令。
.directive('scrollSpy', function ($location, $window) {
以下是我对亚历山大代码的完整翻译:
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');
}
});
}
};
});
如果浏览器滚动到底部,上面的代码也支持突出显示菜单中的最后一个spy
元素,原始代码没有。
答案 1 :(得分:0)
如果您不使用ng-include更改以下条件
if (spyElems[spy.id].offset() === undefined) {
continue;
}
在此
if (spyElems[spy.id].offset() === undefined) {
// try to refind it
spyElems[spy.id] = elem.find('#' + spy.id);
if(spyElems[spy.id].offset() === undefined)
continue;
}