Как исправить элемент после прокрутки на веб-странице AngularJS
Недавно я сделал сайт в AngularJs. Я все еще в фазе обучения.
Я хочу зафиксировать элемент на странице после того, как он достиг вершины. Я пробовал всевозможные функции Javascript и JQuery. Однако они, похоже, не работают.
Я также попытался использовать Angular UI ui-scrollfix, но он также не работает.
Я делюсь своим кодом. Это частичная страница. Пожалуйста, посоветуйте мне метод достижения вышеупомянутого эффекта.
<div class="row pdiv">
<div class="col-md-8 pdiv col-md-offset-2">
<h3><b>About Us</b></h3>
<ul class="nav nav-justified">
<li role="presentation"><a href="" ng-click="scrollTo('weAre')">What are we?</a></li>
<li role="presentation"><a href="" ng-click="scrollTo('brandsAssociation')">Brands Associations</a></li>
<li role="presentation"><a href="" ng-click="scrollTo('knowUs')">Know Us</a></li>
<li role="presentation"><a href="" ng-click="scrollTo('motto')">Our Motto</a></li>
</ul>
</div>
<div id="weAre" class="col-md-8 pdiv col-md-offset-2">
<br>
<h4><b>What are we?</b></h4>
<p>Some content goes here.</p>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
<div id="brandsAssociation" class="col-md-8 pdiv col-md-offset-2">
<br>
<h4><b>Brands Associations</b></h4>
<p>Some content goes here.</p>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
<div id="knowUs" class="col-md-8 pdiv col-md-offset-2">
<br>
<h4><b>Know Us</b></h4>
<p>Some content goes here.</p>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
<div id="motto" class="col-md-8 pdiv col-md-offset-2">
<br>
<h4><b>Our Motto</b></h4>
<p>Some content goes here.</p>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
</div>
<a href="" ng-click="scrollTo('header')"><span id="toTop" class="glyphicon glyphicon-chevron-up"></span></a>
Мне нужно исправить класс ul.nav.nav-justified после того, как он попал в верхнюю часть страницы.
Я использую bootstrap.
Вот зависимости от javascript.
<script src="angular/angular.min.js"></script>
<script src="angular/angular-route.js"></script>
<script src="js/jquery.js"></script>
<script src="js/bootstrap.min.js"></script>
Пожалуйста, помогите...
Ответы
Ответ 1
Чтобы зафиксировать ваш ul
вверху, когда он попадает в верхнюю часть страницы прокрутки, вы можете поместить на него директиву, которая проверяет окно scrollTop() превышает элемент ul
offset верх. Когда это происходит, директива может просто добавить класс к элементу, который фиксирует его в верхней части.
Таким образом, ваша разметка ul
будет выглядеть так: с новой директивой set-class-when-at-top
на ней:
<ul class="nav nav-justified" set-class-when-at-top="fix-to-top">
Эта директива добавит класс CSS fix-to-top
к элементу, когда элемент попадает в верхнюю часть страницы. Определение директивы будет выглядеть так:
app.directive('setClassWhenAtTop', function ($window) {
var $win = angular.element($window); // wrap window object as jQuery object
return {
restrict: 'A',
link: function (scope, element, attrs) {
var topClass = attrs.setClassWhenAtTop, // get CSS class from directive attribute value
offsetTop = element.offset().top; // get element offset top relative to document
$win.on('scroll', function (e) {
if ($win.scrollTop() >= offsetTop) {
element.addClass(topClass);
} else {
element.removeClass(topClass);
}
});
}
};
});
Если вы хотите немного нахально, вы можете даже уменьшить свой обработчик scroll
до одной строки:
$win.on('scroll', function (e) {
element[($win.scrollTop() >= offsetTop) ? 'addClass' : 'removeClass'](topClass);
});
И класс fix-to-top
CSS просто будет примерно таким:
.fix-to-top {
position: fixed;
top: 0;
}
Здесь fiddle.
Ответ 2
Я начал использовать MikeJ большой ответ, чтобы начать, но быстро понял несколько недостатков:
- Не учитывалось, когда содержимое выше элемента изменяется динамически после первого анализа директивы
- Содержимое под фиксированным элементом перемещалось вверх по высоте элемента, когда оно фиксировалось и было удалено из обычного потока документов.
- Если этот элемент фиксируется под чем-то другим (например, в верхнем меню), у вас могут возникнуть проблемы с вычислением правильного места; вам нужно исправить его до того, как
offset top
пройдет, где находится $win.scrollTop()
, так что он не исчезнет за этим меню, а затем зафиксируется после.
Чтобы исправить это, я придумал модифицированную версию:
function setClassWhenAtTop($window) {
var $win = angular.element($window);
return {
restrict: "A",
link: function (scope, element, attrs) {
var topClass = attrs.setClassWhenAtTop,
topPadding = parseInt(attrs.paddingWhenAtTop, 10),
parent = element.parent(),
offsetTop;
$win.on("scroll", function () {
// dynamic page layout so have to recalculate every time;
// take offset of parent because after the element gets fixed
// it now has a different offset from the top
offsetTop = parent.offset().top - topPadding;
if ($win.scrollTop() >= offsetTop) {
element.addClass(topClass);
parent.height(element.height());
} else {
element.removeClass(topClass);
parent.css("height", null);
}
});
}
};
}
Это требует, чтобы элемент, который вы исправляете, был обернут в пустой родительский элемент, содержащий только элемент для исправления. Это должно обрабатывать как знание того, где исходное смещение элемента (для возврата его в поток документа), так и для того, чтобы высота исходного элемента сохраняла поток документа как есть. Кроме того, передайте атрибут для paddingWhenAtTop
, чтобы исправить его раньше (или позже, если это необходимо).
Использование в HTML изменяется следующим образом:
<div>
<ul class="nav nav-justified" set-class-when-at-top="fix-to-top" padding-when-at-top="50">
</div>
Ответ 3
Вот моя попытка сделать его полным angularjs:
JS
.directive('setClassWhenAtTop', ['$window', function($window) {
var $win = angular.element($window); // wrap window object as jQuery object
return {
restrict: 'A',
link: function (scope, element, attrs)
{
var topClass = attrs.setClassWhenAtTop, // get CSS class from directive attribute value
topPadding = parseInt(attrs.paddingWhenAtTop, 10),
offsetTop = element.prop('offsetTop'); // get element offset top relative to document
$win.on('scroll', function (e) {
if ($window.pageYOffset + topPadding >= offsetTop) {
element.addClass(topClass);
} else {
element.removeClass(topClass);
}
});
}
};
}])
CSS
.fix-to-top {
position: fixed;
top: 55px;
height: 50px;
z-index: 999;
width: 100%;
}
HTML
<div class="navigation-bar" set-class-when-at-top="fix-to-top" padding-when-at-top="55">
...
Основные изменения для пропуска jQuery:
parent.offset().top => element.prop('offsetTop')
$win.scrollTop() => $window.pageYOffset
Совет дня:
Не могли бы вы прекратить всегда давать ответы на вопросы по jQuery? Или, по крайней мере, четко указывать это в своем названии или в ваших требованиях к ответам;-)