Ich versuche, ein schnelles Navigationsgerät richtig zum Laufen zu bringen. Es schwebt auf der Seite. Wenn sie auf einen Link klicken, gelangen sie zu dieser ID auf der Seite. Ich folge diesem Leitfaden von Treehouse . Folgendes habe ich für das Scrollen:
$("#quickNav a").click(function(){
var quickNavId = $(this).attr("href");
$("html, body").animate({scrollTop: $(location).offset().top}, "slow");
return false;
});
Ich habe es zunächst vor das gestellt </body>
. Aber ich scheine in eine Rennbedingung zu geraten, in der das ausgelöst wurde, bevor das quickNav kompiliert wurde (es ist darauf ng-hide
platziert, nicht sicher, ob es das verursacht - aber es befindet sich im DOM).
Wenn ich diesen Codeblock in der Konsole ausführe, funktioniert das Scrollen wie erwartet.
Ich dachte, es wäre effektiver, dies in den Controller zu verschieben - oder eher innerhalb einer Direktive. Aber ich habe kein Glück, das zu erreichen. Wie kann ich diesen Codeblock für AngularJS verwenden?
if
Am Ende habe ich mehrere Codezeilen aus Ihrer Bearbeitung entfernt (meistens nur den Block). Das würde verwendet, um zu einem Element zu scrollen, auf das geklickt wurde (wie Sie in Ihrem Plunker gezeigt haben). Richtig? Nur damit es modularer wäre?Dies ist eine bessere Richtlinie, falls Sie sie verwenden möchten:
Sie können zu jedem Element auf der Seite scrollen:
.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"); }); } }})
Verwendung (zum Beispiel klicken Sie auf div 'back-to-top', um zu id scroll-top zu scrollen):
<a id="top-scroll" name="top"></a> <div class="back-to-top" scroll-to-item scroll-to="#top-scroll">
Es wird auch von Chrome, Firefox, Safari und IE aufgrund des HTML-Body-Elements unterstützt.
quelle
scroll-to-item=".selector"
?Um ein bestimmtes Element in einem Bildlaufcontainer zu animieren (fester 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"); }
quelle
Eine eckige Lösung mit $ 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(); }; });
Und hier ist ein Plunk: http://plnkr.co/edit/xi2r8wP6ZhQpmJrBj1jM?p=preview
Und wenn Sie sich für eine reine Javascript-Lösung interessieren, finden Sie hier eine:
Rufen Sie runScroll in Ihrem Code mit der übergeordneten Container-ID und der Ziel-Scroll-ID auf:
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); }
Referenz: Browserübergreifendes JavaScript (nicht jQuery ...) zur oberen Animation scrollen
quelle
Danke Andy für das Beispiel, das war sehr hilfreich. Ich habe die Implementierung einer etwas anderen Strategie beendet, da ich einen einseitigen Bildlauf entwickle und nicht wollte, dass Angular bei Verwendung der Hashbang-URL aktualisiert wird. Ich möchte auch die Vorwärts- / Rückwärtsbewegung des Browsers beibehalten.
Anstatt die Direktive und den Hash zu verwenden, verwende ich einen $ scope. $ Watch auf der $ location.search und erhalte das Ziel von dort. Dies ergibt einen schönen sauberen Ankertag
<a ng-href="#/?scroll=myElement">My element</a>
Ich habe den Watchcode wie folgt an meine Moduldeklaration in app.js gekettet:
.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"); }); })
Die Einschränkung mit dem obigen Code besteht darin, dass das DOM möglicherweise nicht rechtzeitig für den Aufruf von jQuery $ target.offset () geladen wird, wenn Sie über eine URL direkt von einer anderen Route aus zugreifen. Die Lösung besteht darin, diesen Code in einem $ viewContentLoaded-Watcher zu verschachteln. Der endgültige Code sieht ungefähr so aus:
.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"); }); }); })
Getestet mit Chrome und FF
quelle
Ich habe Andrew Joslins Antwort verwendet, die großartig funktioniert, aber eine Änderung der Winkelroute ausgelöst hat, die für mich eine nervös aussehende Schriftrolle erzeugt hat. Wenn Sie vermeiden möchten, dass eine Routenänderung ausgelöst wird,
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; }); } } });
quelle
Was ist mit Angular-Scroll , es wird aktiv gepflegt und es gibt keine Abhängigkeit von jQuery.
quelle
Ein weiterer Vorschlag. Eine Direktive mit Selektor.
HTML:
<button type="button" scroll-to="#catalogSection">Scroll To</button>
Winkel:
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 }); } }); } } });
Beachten Sie auch $ anchorScroll
quelle
Sehr klare Antwort, nur mit ANGULARJS, keine JQUERY hängt davon ab
in Ihrem HTML irgendwo unten
<back-top>some text</back-top>
in Ihrem HTML irgendwo oben
<div id="top"></div>
in deinem 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']); }); } }; }]);
quelle