Javascript 如何在 AngularJS 网页中滚动后修复元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27211881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to fix an element after scroll in an AngularJS webpage
提问by Anjul Garg
I recently made a website in AngularJs. I am still in the learning phase. I wish to fix an element on a page after it reaches the top. I have tried all sorts of Javascript and Jquery functions. However, they don't seem to be working.
我最近在 AngularJs 中做了一个网站。我还在学习阶段。我希望在到达顶部后修复页面上的元素。我尝试了各种 Javascript 和 Jquery 函数。但是,它们似乎不起作用。
I also tried using Angular UI's ui-scrollfix but it is also not working.
我也尝试使用 Angular UI 的 ui-scrollfix 但它也不起作用。
I am sharing my code. It is a partial page. Please advise me a method to achieve the above mentioned effect.
我正在分享我的代码。它是部分页面。请告诉我一种实现上述效果的方法。
<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>
I need to fix the ul class .nav .nav-justified after it hits the top of the page.
我需要在它到达页面顶部后修复 ul 类 .nav .nav-justified 。
I am using bootstrap.
我正在使用引导程序。
here are the javascript dependencies.
这是 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>
Please help...
请帮忙...
回答by MikeJ
To fix your ulto the top when it hits the top of the page on scroll, you can put a directive on it that checks for the window's scrollTop()exceeding the ulelement's offsettop. When that occurs, the directive can just add a class to the element that fixes it to the top.
要ul在滚动时到达页面顶部时将其固定到顶部,您可以在其上放置一个指令来检查窗口的scrollTop() 是否超过ul元素的顶部偏移量。发生这种情况时,该指令可以将一个类添加到将其固定到顶部的元素。
So your ulmarkup would look like this, with new directive set-class-when-at-topon it:
所以你的ul标记看起来像这样,上面有新的指令set-class-when-at-top:
<ul class="nav nav-justified" set-class-when-at-top="fix-to-top">
That directive would add the CSS class fix-to-topto the element when the element hits the top of the page. The directive definition would look like this:
fix-to-top当元素到达页面顶部时,该指令会将 CSS 类添加到元素中。指令定义如下所示:
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's attribute value
offsetTop = element.offset().top; // get element's offset top relative to document
$win.on('scroll', function (e) {
if ($win.scrollTop() >= offsetTop) {
element.addClass(topClass);
} else {
element.removeClass(topClass);
}
});
}
};
});
If you wanted to get a bit cheeky, you could even reduce your scrollhandler to just one line:
如果你想变得有点厚颜无耻,你甚至可以将你的scroll处理程序减少到只有一行:
$win.on('scroll', function (e) {
element[($win.scrollTop() >= offsetTop) ? 'addClass' : 'removeClass'](topClass);
});
And the fix-to-topCSS class would just be something like this:
而fix-to-topCSS 类将是这样的:
.fix-to-top {
position: fixed;
top: 0;
}
Here's a fiddle.
这是一个小提琴。
回答by RebelFist
I started using MikeJ's great answer to get started, but quickly realized a few shortcomings:
我开始使用 MikeJ 的好答案开始,但很快就意识到了一些缺点:
- Didn't account for when content above the element changes dynamically after the directive is first parsed
- Content below the fixed element moved up the height of the element when it became fixed and was removed from the normal document flow
- If this element is being fixed below something else (like a top menu) you may have some trouble calculating the right spot; you need to fix it before the
offset topis past where the$win.scrollTop()is, so that it doesn't disappear behind that menu and then get fixed after.
- 没有考虑在指令第一次解析后元素上方的内容何时动态变化
- 当固定元素下方的内容固定并从正常文档流中删除时,它会向上移动元素的高度
- 如果这个元素被固定在其他东西下面(比如顶部菜单),你可能会在计算正确的位置时遇到一些麻烦;你需要在它
offset top过去之前修复它$win.scrollTop(),这样它就不会消失在那个菜单后面,然后再修复。
To fix these, I came up with a modified version:
为了解决这些问题,我想出了一个修改版本:
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);
}
});
}
};
}
This requires the element you are fixing to be wrapped in an empty parent that only contains the element to fix. This is to handle both knowing where the original offset of the element was (for putting it back into the document flow) and to have the height of the original element to keep the document flow as it was. In addition, pass in an attribute for paddingWhenAtTopto fix it sooner (or later if desired).
这需要将您要修复的元素包装在仅包含要修复的元素的空父元素中。这是为了处理知道元素的原始偏移量在哪里(用于将其放回文档流)和具有原始元素的高度以保持文档流原样。此外,传入一个属性 forpaddingWhenAtTop以尽快(或根据需要,稍后)修复它。
Usage in the HTML changes like so:
HTML 中的用法更改如下:
<div>
<ul class="nav nav-justified" set-class-when-at-top="fix-to-top" padding-when-at-top="50">
</div>
回答by hugsbrugs
Here is my attempt to make it full angularjs :
这是我尝试使其成为完整的 angularjs :
JS
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's attribute value
topPadding = parseInt(attrs.paddingWhenAtTop, 10),
offsetTop = element.prop('offsetTop'); // get element's offset top relative to document
$win.on('scroll', function (e) {
if ($window.pageYOffset + topPadding >= offsetTop) {
element.addClass(topClass);
} else {
element.removeClass(topClass);
}
});
}
};
}])
CSS
CSS
.fix-to-top {
position: fixed;
top: 55px;
height: 50px;
z-index: 999;
width: 100%;
}
HTML
HTML
<div class="navigation-bar" set-class-when-at-top="fix-to-top" padding-when-at-top="55">
...
Main changes to skip jquery :
跳过 jquery 的主要变化:
parent.offset().top => element.prop('offsetTop')
$win.scrollTop() => $window.pageYOffset
Tip of the day :Would you please stop always giving angularjs title questions jquery answers ! Or at least indicate it clearly in your title or in your answer requirements ;-)
每日小贴士:请不要总是给 angularjs 标题问题 jquery 答案!或者至少在你的标题或你的回答要求中清楚地表明它;-)

