ScrollTo在AngularJS中的function

我试图让一个快速的导航工作正常。 它漂浮在一边。 当他们点击一个链接时,会把它们带到页面上的那个ID上。 我正在从树屋中遵循这个指南 。 这是我的滚动:

$("#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合作?

这是一个简单的指令,将在点击时滚动到一个元素:

 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

有关创build指令的帮助,请查看http://egghead.io上的video,从#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的元素。

如果您想使用它,这是一个更好的指示:

你可以滚动到页面中的任何元素:

 .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'back-to-top'将滚动到id scroll-top):

 <a id="top-scroll" name="top"></a> <div class="back-to-top" scroll-to-item scroll-to="#top-scroll"> 

它也支持铬,Firefox,Safari和IE浏览器的HTML,身体元素的原因。

为了animation到一个滚动容器(固定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"); } 

使用$ anchorScroll的解决schemehttp://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(); }; }); 

这里是一个plunk: http ://plnkr.co/edit/xi2r8wP6ZhQpmJrBj1jM? p= preview

如果你关心一个纯JavaScript解决scheme,这里是一个:

在代码中用父容器ID和目标滚动ID调用runScroll:

 function 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); } 

参考: 跨浏览器JavaScript(不是jQuery …)滚动到顶部的animation

感谢Andy的例子,这非常有帮助。 我开始实施一个略有不同的策略,因为我正在开发一个单页滚动,并不希望使用hashbang URL时刷新Angular。 我也想保留浏览器的后退/前进动作。

而不是使用指令和散列,我使用$ location.search的$ scope。$ watch,并从那里获取目标。 这给了一个很好的干净的锚标记

<a ng-href="#/?scroll=myElement">My element</a>

我把watch code链接到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"); }); }) 

上面的代码需要注意的是,如果您通过不同的path直接访问URL,那么可能不会及时为jQuery的$ target.offset()调用加载DOM。 解决scheme是将这个代码嵌套在$ 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进行testing

我用安德鲁乔斯林的答案,这很好,但引发了angular度路线的变化,这为我创造了一个跳动的看起来滚动。 如果您想避免触发路线更改,

 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; }); } } }); 

怎么样的angular度滚动 ,它被积极维护,并没有依赖jQuery ..

另一个build议。 一个指令与select器。

HTML:

 <button type="button" scroll-to="#catalogSection">Scroll To</button> 

angular度:

 app.directive('scrollTo', function () { return { restrict: 'A', link: function (scope, element, attrs) { element.on('click', function () { var target = $(attrs.scrollTo); if (target.length > 0) { $('html, body').animate({ scrollTop: target.offset().top }); } }); } } }); 

另外注意$ anchorScroll

复活这个旧的线程,为一些可能无法使用这些指令的地方添加一个修正。 bodyhtml都不能设置百分比高度,否则没有效果。 自动值可以解决问题,而不会限制页面大小。

 body, html { height: auto; }