我正在努力让快速导航正常工作。它浮在一边。当他们点击链接时,会将他们带到页面上的该ID。我正在关注这个guide from Treehouse。 这就是我滚动的内容:
$("#quickNav a").click(function(){
var quickNavId = $(this).attr("href");
$("html, body").animate({scrollTop: $(location).offset().top}, "slow");
return false;
});
我最初将它放在</body>
之前。但是我似乎遇到了一个竞争条件,即在编译的是quickNav之前触发它(它有一个ng-hide
,不确定是否会导致它 - 但它在DOM内。)
如果我在控制台中运行该代码块,则滚动按预期工作。
我认为将其移入控制器更有效 - 或者更有可能在指令中。但我没有幸运完成那件事。 如何让这段代码与AngularJS一起使用?
答案 0 :(得分:122)
这是一个简单的指令,将在点击时滚动到一个元素:
myApp.directive('scrollOnClick', function() {
return {
restrict: 'A',
link: function(scope, $elm) {
$elm.on('click', function() {
$("body").animate({scrollTop: $elm.offset().top}, "slow");
});
}
}
});
演示:http://plnkr.co/edit/yz1EHB8ad3C59N6PzdCD?p=preview
有关创建指令的帮助,请查看http://egghead.io处的视频,从#10“第一指令”开始。
编辑:要使其滚动到href指定的特定元素,只需选中attrs.href
。
myApp.directive('scrollOnClick', function() {
return {
restrict: 'A',
link: function(scope, $elm, attrs) {
var idToScroll = attrs.href;
$elm.on('click', function() {
var $target;
if (idToScroll) {
$target = $(idToScroll);
} else {
$target = $elm;
}
$("body").animate({scrollTop: $target.offset().top}, "slow");
});
}
}
});
然后您可以像这样使用它:<div scroll-on-click></div>
滚动到单击的元素。或<a scroll-on-click href="#element-id"></div>
滚动到带有id的元素。
答案 1 :(得分:31)
如果您想使用它,这是一个更好的指令:
您可以滚动到页面中的任何元素:
.directive('scrollToItem', function() {
return {
restrict: 'A',
scope: {
scrollTo: "@"
},
link: function(scope, $elm,attr) {
$elm.on('click', function() {
$('html,body').animate({scrollTop: $(scope.scrollTo).offset().top }, "slow");
});
}
}})
用法(例如点击div&#39; back-to-top&#39;将滚动到id滚动顶部):
<a id="top-scroll" name="top"></a>
<div class="back-to-top" scroll-to-item scroll-to="#top-scroll">
它还支持chrome,firefox,safari和IE导致的html,body元素。
答案 2 :(得分:22)
为了动画滚动容器内的特定元素(固定DIV)
/*
@param Container(DIV) that needs to be scrolled, ID or Div of the anchor element that should be scrolled to
Scrolls to a specific element in the div container
*/
this.scrollTo = function(container, anchor) {
var element = angular.element(anchor);
angular.element(container).animate({scrollTop: element.offset().top}, "slow");
}
答案 3 :(得分:6)
使用$ anchorScroll的角度解决方案 http://www.benlesh.com/2013/02/angular-js-scrolling-to-element-by-id.html:
app.controller('MainCtrl', function($scope, $location, $anchorScroll) {
var i = 1;
$scope.items = [{ id: 1, name: 'Item 1' }];
$scope.addItem = function (){
i++;
//add the item.
$scope.items.push({ id: i, name: 'Item ' + i});
//now scroll to it.
$location.hash('item' + i);
$anchorScroll();
};
});
这是一个插件:http://plnkr.co/edit/xi2r8wP6ZhQpmJrBj1jM?p=preview
如果您关心纯粹的JavaScript解决方案,请参阅:
使用父容器ID和目标滚动ID:
在代码中调用runScrollfunction runScroll(parentDivId,targetID) {
var longdiv;
longdiv = document.querySelector("#" + parentDivId);
var div3pos = document.getElementById(targetID).offsetTop;
scrollTo(longdiv, div3pos, 600);
}
function scrollTo(element, to, duration) {
if (duration < 0) return;
var difference = to - element.scrollTop;
var perTick = difference / duration * 10;
setTimeout(function () {
element.scrollTop = element.scrollTop + perTick;
if (element.scrollTop == to) return;
scrollTo(element, to, duration - 10);
}, 10);
}
参考:Cross browser JavaScript (not jQuery...) scroll to top animation
答案 4 :(得分:4)
感谢Andy的例子,这非常有帮助。我开始实现一个略有不同的策略,因为我正在开发单页滚动,并且在使用hashbang URL时不希望Angular刷新。我还想保留浏览器的后退/前进动作。
我没有使用指令和哈希,而是在$ location.search上使用$ scope。$ watch,并从那里获取目标。这给了一个很好的干净锚标记
<a ng-href="#/?scroll=myElement">My element</a>
我将监视代码链接到app.js中的模块声明,如下所示:
.run(function($location, $rootScope) {
$rootScope.$watch(function() { return $location.search() }, function(search) {
var scrollPos = 0;
if (search.hasOwnProperty('scroll')) {
var $target = $('#' + search.scroll);
scrollPos = $target.offset().top;
}
$("body,html").animate({scrollTop: scrollPos}, "slow");
});
})
上面代码的警告是,如果您通过URL直接从不同的路由访问,则可能无法及时加载DOM以进行jQuery的$ target.offset()调用。解决方案是将此代码嵌套在$ viewContentLoaded观察器中。最终的代码看起来像这样:
.run(function($location, $rootScope) {
$rootScope.$on('$viewContentLoaded', function() {
$rootScope.$watch(function() { return $location.search() }, function(search) {
var scrollPos = 0
if (search.hasOwnProperty('scroll')) {
var $target = $('#' + search.scroll);
var scrollPos = $target.offset().top;
}
$("body,html").animate({scrollTop: scrollPos}, "slow");
});
});
})
使用Chrome和FF进行测试
答案 5 :(得分:4)
我使用了安德鲁·乔斯林的答案,这很有效但触发了一个角度路线改变,这为我创造了一个跳跃的外观。如果您想避免触发路线更改,
myApp.directive('scrollOnClick', function() {
return {
restrict: 'A',
link: function(scope, $elm, attrs) {
var idToScroll = attrs.href;
$elm.on('click', function(event) {
event.preventDefault();
var $target;
if (idToScroll) {
$target = $(idToScroll);
} else {
$target = $elm;
}
$("body").animate({scrollTop: $target.offset().top}, "slow");
return false;
});
}
}
});
答案 6 :(得分:2)
angular-scroll如何,它是积极维护的,并且不依赖于jQuery ..
答案 7 :(得分:1)
另一个建议。一个带选择器的指令。
HTML:
ExpandList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {
// get tag from view, it will be better if your check the object type.
Child child = (Child)view.getTag();
return false;
}
});
角:
<button type="button" scroll-to="#catalogSection">Scroll To</button>
另请注意$anchorScroll
答案 8 :(得分:0)
非常明确的答案,只使用ANGULARJS,没有任何JQUERY依赖
在你的html底部的某个地方<back-top>some text</back-top>
<div id="top"></div>
的某个地方
在你的js中:
/**
* @ngdoc directive
* @name APP.directive:backTop
<pre>
<back-top></back-top>
</pre>
*/
angular
.module('APP')
.directive('backTop', ['$location', '$anchorScroll' ,function($location, $anchorScroll) {
return {
restrict: 'E',
replace: true,
transclude: true,
template: '<span class=\'btn btn-mute pull-right\'><i class=\'glyphicon glyphicon-chevron-up\'></i><ng-transclude></ng-transclude></span>',
scope: {
},
link: function(scope, element) {
element.on('click', function(event) {
$anchorScroll(['top']);
});
}
};
}]);
答案 9 :(得分:0)
使用元素的ID滚动到目标div
指令(Angular 1)
angular.module("App") // Module Name
.directive('scrollOnClick', function () {
return {
restrict: 'A',
scope: {
scrollTo: "@"
},
link: function (scope, $elm, attrs) {
//var idToScroll = attrs.href;
$elm.on('click', function () {
$('html,body').animate({ scrollTop: $(scope.scrollTo).offset().top }, "slow");
});
}
}
});
HTML 代码
<!-- Click to scroll -->
<a scroll-on-click scroll-to="#scheduleDiv">Click here to Scroll to Div With Id ""</a>
<!-- scrollable / target div -->
<div id="scheduleDiv">Test scrolling ... You are able to view me on click of above anchor tag.</div>