Hızlı bir nav'ın düzgün çalışmasını sağlamaya çalışıyorum. Yan tarafta yüzüyor. Bir bağlantıya tıkladıklarında, onları sayfadaki o kimliğe götürüyor. Bu Treehouse'daki kılavuz'i takip ediyorum. Kaydırma için sahip olduğum şey bu:
$("#quickNav a").click(function(){
var quickNavId = $(this).attr("href");
$("html, body").animate({scrollTop: $(location).offset().top}, "slow");
return false;
});
Başlangıçta </body>
den önce yerleştirdim. Ancak, quickNav derlenmeden önce bunun ateşlendiği bir yarış koşuluyla karşılaşıyor gibiyim (üzerine yerleştirilmiş bir ng-hide
var, buna neden olup olmadığından emin değilim - ancak DOM içinde).
Bu kod bloğunu konsolda çalıştırırsam, kaydırma beklendiği gibi çalışır.
Bunu denetleyiciye taşımanın daha etkili olacağını düşündüm - ya da daha büyük olasılıkla bir yönerge içinde. Ama bunu başarma şansım yok. **Bu kod bloğunun AngularJS ile çalışmasını nasıl sağlayabilirim?
İşte tıklandığında bir öğeye kaydırma yapacak basit bir yönerge:
myApp.directive('scrollOnClick', function() {
return {
restrict: 'A',
link: function(scope, $elm) {
$elm.on('click', function() {
$("body").animate({scrollTop: $elm.offset().top}, "slow");
});
}
}
});
Demo: http://plnkr.co/edit/yz1EHB8ad3C59N6PzdCD?p=preview
Yönerge oluşturma konusunda yardım almak için http://egghead.io adresindeki #10 "ilk yönerge" ile başlayan videolara göz atın.
düzenle: Bir href ile belirtilen belirli bir öğeye kaydırma yapmak için attrs.href
seçeneğini işaretlemeniz yeterlidir.
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");
});
}
}
});
O zaman bunu şu şekilde kullanabilirsiniz: <div scroll-on-click></div>
tıklanan öğeye kaydırmak için. Veya <a scroll-on-click href="#element-id"></div>
id'li elemana kaydırmak için.
Kullanmak istemeniz durumunda bu daha iyi bir yönergedir:
sayfadaki herhangi bir öğeye kaydırabilirsiniz:
.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");
});
}
}})
Kullanım (örneğin div 'back-to-top' üzerine tıklandığında id scroll-top'a kaydırılır):
<a id="top-scroll" name="top"></a>
<div class="back-to-top" scroll-to-item scroll-to="#top-scroll">
Ayrıca html,body elementi nedeniyle chrome,firefox,safari ve IE tarafından da desteklenmektedir.
Örnek için teşekkürler Andy, çok yardımcı oldu. Tek sayfalık bir kaydırma geliştirdiğim ve hashbang URL'sini kullanırken Angular'ın yenileme yapmasını istemediğim için biraz farklı bir strateji uyguladım. Ayrıca tarayıcının geri/ileri hareketini de korumak istiyorum.
Yönerge ve hash kullanmak yerine, $location.search üzerinde bir $scope.$watch kullanıyorum ve hedefi buradan elde ediyorum. Bu güzel ve temiz bir bağlantı etiketi sağlıyor
<a ng-href="#/?scroll=myElement">Benim öğem</a>
Watch kodunu app.js'deki my module bildirimine şu şekilde zincirledim:
.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");
});
})
Yukarıdaki kodla ilgili uyarı, URL'ye doğrudan farklı bir rotadan erişirseniz, DOM'un jQuery'nin $target.offset() çağrısı için zamanında yüklenemeyebileceğidir. Çözüm, bu kodu bir $viewContentLoaded izleyicisinin içine yerleştirmektir. Son kod aşağıdaki gibi görünür:
.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 ve FF ile test edildi