Bootstrap data-spy="affix" 不适用于 Angular 视图更改
Posted
技术标签:
【中文标题】Bootstrap data-spy="affix" 不适用于 Angular 视图更改【英文标题】:Bootstrap data-spy="affix" not working on Angular View change 【发布时间】:2014-07-01 13:55:25 【问题描述】:我试图弄清楚为什么当我更改 Angular 视图时我的affix
-ed 面板没有保持原样。
我已将 affix 属性直接添加到第一页(详细信息)的面板中,并将其仅留在第二页(航班)的 data-spy 中。
在完整的网络版本中,如果我刷新航班页面,词缀会突然启动,并在我滚动时保持不变,但如果我只是使用 Angular 导航到该页面,则不会。
当我在视图之间导航时,Bootstrap 似乎没有将词缀添加到类中。
HTML:
<div class="panel panel-primary mySidebar" id="sidebar"
data-spy="affix" data-offset-top="0" data-offset-bottom="200">
CSS:
.mySidebar.affix
position: fixed;
top: 250px;
.mySidebar.affix-bottom
position: absolute;
top: auto;
bottom: 450px;
这是一个Plunker..
http://plnkr.co/edit/S0Bc50?p=preview
我在这里发现了一个类似的问题:
Twitter Bootstrap: Affix not triggering in single page application
但我不知道如何将其应用于我的问题......
任何帮助都会很棒!
【问题讨论】:
您考虑过使用github.com/angular-ui/bootstrap 吗? 我实际上没有... 这有什么帮助?干杯! @cvrebert Angular UI Bootstrap 似乎没有 Affix 指令 但是 Angular UI Utils 有一个 Scrollfix 指令 你也可以只从组件触发它。它工作我试过getbootstrap.com/docs/3.4/javascript/#via-javascript-5 【参考方案1】:Angular UI Utils(not Angular UI Bootstrap,如 cmets 中所述)有一个 Scrollfix 指令,可以用来代替 Affix。我遇到了和你一样的问题,改变视图后 Affix 不起作用。我尝试将 Angular UI Scrollfix 添加到我的应用程序中,到目前为止它看起来可以满足我的需求。
这是我发现的一篇有用的 Stack Overflow 帖子,其中包含更多解释和示例:Angular ui-utils scrollfix。
【讨论】:
谢谢...我会试一试的!【参考方案2】:如果您不想使用 UI Bootstrap 或 UI Utils 来支持普通的旧 Bootstrap 3 词缀,那么这个词缀指令包装器在我的单页 Angular 应用程序上对我很有用。我正在使用 AngularUI 路由器。
第一次加载指令时应用词缀。然后在$stateChagneSuccess
上清除它:$element.removeData('bs.affix').removeClass('affix affix-top affix-bottom');
如此处所示:Resetting / changing the offset of bootstrap affix,然后重新应用它。如果我在这里做的任何事情都很难看,请告诉我,尽管我喜欢简单并且喜欢利用默认的 Bootstrap JS 库。
myApp.directive('affix', ['$rootScope', '$timeout', function($rootScope, $timeout)
return
link: function($scope, $element, $attrs)
function applyAffix()
$timeout(function()
$element.affix( offset: top: $attrs.affix );
);
$rootScope.$on('$stateChangeSuccess', function()
$element.removeData('bs.affix').removeClass('affix affix-top affix-bottom');
applyAffix();
);
applyAffix();
;
]);
【讨论】:
【参考方案3】:我更喜欢挂钩原始的 data-spy="scroll"
引导绑定 - 以便更好地从 clickdummy 迁移到生产环境 - 并将原始引导功能应用于它,因为 Angular-UI(至少对我而言)是不可接受的混乱。
(function ()
'use strict';
angular
.module('app.core')
.directive('spy', spy);
function spy()
return
restrict: 'A',
link: link
;
function link(scope, element, attrs)
// Dom ready
$(function ()
if (attrs.spy === 'affix')
$(element).affix(
offset:
top: attrs.offsetTop || 10
// bottom: attrs.offsetBottom || 10
);
);
)();
【讨论】:
【参考方案4】:这是一个老问题,但我最近在将我的网站重写为 AngularJS 应用程序时偶然发现了这个问题。我也在使用 Bootstrap Affix 插件(包括在滚动时更新活动类),但无法找到与我正在寻找的功能非常相似的插件,所以我编写了自己的指令。
查看实际操作:http://bobbograph.com/#/api
注意:提供给指令的值是顶部偏移量。
JavaScript:
https://github.com/robertmesserle/Bobbograph/blob/v3/www/js/site.js#L102
app.directive('rmAffix', function ($window)
var body = document.body,
win = document.defaultView,
docElem = document.documentElement,
isBoxModel = (function ()
var box = document.createElement('div'),
isBoxModel;
box.style.paddingLeft = box.style.width = "1px";
body.appendChild(box);
isBoxModel = box.offsetWidth == 2;
body.removeChild(box);
return isBoxModel;
)();
function getTop (element)
var box = element.getBoundingClientRect(),
clientTop = docElem.clientTop || body.clientTop || 0,
scrollTop = win.pageYOffset || isBoxModel && docElem.scrollTop || body.scrollTop;
return box.top + scrollTop - clientTop;
return function ($scope, $element, $attrs)
var offset = $scope.$eval($attrs.rmAffix),
elemTop = getTop($element[0]),
$links = $element.find('li'),
linkTops = [];
angular.forEach($links, function ($link)
var $a = angular.element($link).find('a'),
href = $a.attr('href').substr(1),
target = document.getElementById(href),
elemTop = getTop(target);
linkTops.push(elemTop);
$a.on('click', function (event)
window.scrollTo(0, elemTop - offset);
event.preventDefault();
);
);
angular.element($window).on('scroll', function (event)
var top = window.pageYOffset,
index;
if (top > elemTop - offset) $element.addClass('affix');
else $element.removeClass('affix');
//-- remove selected class from all links
$links.removeClass('active');
//-- find the closest element
for (index = 1; index < linkTops.length; index++)
if (linkTops[index] - 100 > top) break;
angular.element($links[index - 1]).addClass('active');
);
;
);
html(翡翠)
https://github.com/robertmesserle/Bobbograph/blob/v3/www/api.jade#L288
ul.nav.nav-stacked.nav-pills(rm-affix=70)
li.active: a( href="#basic" ) Basic Usage
li: a( href="#options" ) Options
li: a( href="#data" ) Data
li: a( href="#padding" ) Padding
【讨论】:
【参考方案5】:它不起作用,因为特定事件不会在词缀绑定到时触发。在您的情况下的单页应用程序中,页面仅加载一次,因此绑定到页面加载和类似事件的任何逻辑都会失败。如果您重新加载页面,一切都会好起来的。
解决方法是使用棱角分明的方式。其中一个 cmets 建议尝试使用 angular-strap,因为它具有用于完全相同目的的 affix 指令。
我遇到了类似的情况,最终使用了MacGyver,效果非常好,而且使用简单。
【讨论】:
谢谢...我会试一试的!以上是关于Bootstrap data-spy="affix" 不适用于 Angular 视图更改的主要内容,如果未能解决你的问题,请参考以下文章