Javascript 如何处理AngularJS中的锚散列链接
你们中有谁知道如何很好地处理AngularJS中的锚散列链接吗 对于一个简单的FAQ页面,我有以下标记Javascript 如何处理AngularJS中的锚散列链接,javascript,angularjs,anchor,hashtag,Javascript,Angularjs,Anchor,Hashtag,你们中有谁知道如何很好地处理AngularJS中的锚散列链接吗 对于一个简单的FAQ页面,我有以下标记 <a href="#faq-1">Question 1</a> <a href="#faq-2">Question 2</a> <a href="#faq-3">Question 3</a> <h3 id="faq-1">Question 1</h3> <h3 id="faq-2">Q
<a href="#faq-1">Question 1</a>
<a href="#faq-2">Question 2</a>
<a href="#faq-3">Question 3</a>
<h3 id="faq-1">Question 1</h3>
<h3 id="faq-2">Question 2</h3>
<h3 id="fa1-3">Question 3</h3>
问题1
问题2
问题3
当点击以上任何一个链接时,AngularJS截取并将我路由到一个完全不同的页面(在我的例子中,是404页面,因为没有与链接匹配的路由。)
我的第一个想法是创建一个路由匹配“/faq/:chapter”并在相应的控制器中检查匹配元素后的$routeParams.chapter
,然后使用jQuery向下滚动到它
但是AngularJS又在我身上大便了,而且还是滚动到页面的顶部
那么,这里有人在过去做过类似的事情,并且知道一个很好的解决方案吗
编辑:切换到HTML5模式应该可以解决我的问题,但无论如何我们都必须支持IE8+,所以我担心这不是一个可接受的解决方案://这里有一种肮脏的解决方法,创建自定义指令,滚动到指定的元素(带有硬编码的“faq”)
尝试为角度路由设置哈希前缀
$locationProvider.hashPrefix(“!”)
完整示例:
angular.module('app',[])
.config(['$routeProvider','$locationProvider',
函数($routeProvider,$locationProvider){
$routeProvider.when(…);
$locationProvider.hashPrefix(“!”);
}
])
您正在寻找的
基本上,您只需插入它并在控制器中调用它,它就会将您滚动到在$location.hash()中找到id的任何元素
您的链接如下所示:
<a href="#/test?scrollTo=foo">Test/Foo</a>
<a href="#/test#foo">Test/Foo</a>
href="#/route#anchorID
您的链接如下所示:
<a href="#/test?scrollTo=foo">Test/Foo</a>
<a href="#/test#foo">Test/Foo</a>
href="#/route#anchorID
在我的例子中,我注意到如果我修改了$location.hash()
,路由逻辑就会启动。下面的伎俩奏效了
$scope.scrollTo = function(id) {
var old = $location.hash();
$location.hash(id);
$anchorScroll();
//reset to old to keep any additional routing logic from kicking in
$location.hash(old);
};
这是我的解决方案,它使用了一个看起来更具角度y的指令,因为我们处理的是DOM:
代码
HTML
嗨,我是第一组
僵尸ipsum reversus ab病毒地狱,nam rick grimes malum大脑。卡恩伐木业公司是一家大型企业。
大脑的最高点, 莫博·维尔马莱菲西亚?《末日启示录》戈尔格·奥梅罗不死族幸存者格言毛里斯。
嗨,无知的死尸,没有灵魂的造物主,我是邪恶的追踪者,基督复临门,邪恶的秃鹫,在活体小脑上。
奈斯西奥在一个不死僵尸的大脑里工作。苹果腐烂的巫毒恐怖。快死了。
我完全支持第二节
僵尸ipsum reversus ab病毒地狱,nam rick grimes malum大脑。卡恩伐木业公司是一家大型企业。
大脑的最高点, 莫博·维尔马莱菲西亚?《末日启示录》戈尔格·奥梅罗不死族幸存者格言毛里斯。
嗨,无知的死尸,没有灵魂的造物主,我是邪恶的追踪者,基督复临门,邪恶的秃鹫,在活体小脑上。
奈斯西奥在一个不死僵尸的大脑里工作。苹果腐烂的巫毒恐怖。快死了。
我用了$anchorScroll服务。为了抵消散列更改带来的页面刷新,我继续并取消了locationChangeStart事件。这对我来说很有效,因为我有一个连接到ng开关的帮助页面,刷新会严重破坏应用程序 如果您总是知道路线,您可以像这样简单地附加锚点:
<a href="#/test?scrollTo=foo">Test/Foo</a>
<a href="#/test#foo">Test/Foo</a>
href="#/route#anchorID
其中,route
是当前角度路由,anchorID
与页面上某个地方的
匹配,您可以尝试使用
因此,控制器将是:
app.controller('MainCtrl', function($scope, $location, $anchorScroll, $routeParams) {
$scope.scrollTo = function(id) {
$location.hash(id);
$anchorScroll();
}
});
以及以下观点:
<a href="" ng-click="scrollTo('foo')">Scroll to #foo</a>
<a href="" ng-click="scrollTo(id)">Text</a>
…锚id没有秘密:
<div id="foo">
This is #foo
</div>
这是#福
问题1
问题2
问题3
这可能是ngView的一个新属性,但我已经能够使用ngView autoscroll
属性和“双哈希”使其锚定哈希链接与angular route
一起工作
(以下代码与角带一起使用)
我在应用程序的路由逻辑中解决了这个问题
function config($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '/partials/search.html',
controller: 'ctrlMain'
})
.otherwise({
// Angular interferes with anchor links, so this function preserves the
// requested hash while still invoking the default route.
redirectTo: function() {
// Strips the leading '#/' from the current hash value.
var hash = '#' + window.location.hash.replace(/^#\//g, '');
window.location.hash = hash;
return '/' + hash;
}
});
}
我试图让我的Angular应用程序滚动到anchor opon加载,但遇到了$routeProvider的URL重写规则
经过长时间的实验,我决定:
从的.run()部分注册document.onload事件处理程序
角度应用程序模块李>
在处理程序中,找出原始
has锚定标记应该是通过执行一些字符串操作来实现的
使用剥离的锚标记覆盖location.hash(其中
使$routeProvider立即用它的
“#/”规则。但这很好,因为角度现在与
URL中发生了什么4)调用$anchorScroll()
angular.module(“bla”,[])。})
.run(函数($location,$anchorScroll){
$(文档).ready(函数(){
if(location.hash&&location.hash.length>=1){
var path=location.hash;
var potentialAnchor=path.substring(path.lastIndexOf(“/”)+1);
如果($(“#”+potentialAnchor).length>0){//请确保此标签存在于文档中。
location.hash=potentialAnchor;
$anchorScroll();
}
}
})
我不能100%确定这是否一直有效,但在我的应用程序中,这给了我预期的行为
假设您在关于页面上,您有以下路线:
yourApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/about', {
templateUrl: 'about.html',
controller: 'AboutCtrl'
}).
otherwise({
redirectTo: '/'
});
}
]);
现在,在你的HTML
<ul>
<li><a href="#/about#tab1">First Part</a></li>
<li><a href="#/about#tab2">Second Part</a></li>
<li><a href="#/about#tab3">Third Part</a></li>
</ul>
<div id="tab1">1</div>
<div id="tab2">2</div>
<div id="tab3">3</div>
1.
2.
3.
总之
在主播帮我搞定之前包括页面名称。
让我知道你的想法
下跌趋势
这将重新呈现页面,然后滚动到锚点
更新
<ul>
<li><a href="#/about#tab1">First Part</a></li>
<li><a href="#/about#tab2">Second Part</a></li>
<li><a href="#/about#tab3">Third Part</a></li>
</ul>
<div id="tab1">1</div>
<div id="tab2">2</div>
<div id="tab3">3</div>
<a href="#tab1" onclick="return false;">First Part</a>
$scope.$on('$routeChangeSuccess', function () {
window.scrollTo(0, 0);
});
$scope.scrollTo = function(id) {
var old = $location.hash();
$location.hash(id).replace();
$anchorScroll();
};
<a href="#/#faq-1">Question 1</a>
<a href="/#/#faq-1">Question 1</a>
<a href="/#/#faq-2">Question 2</a>
<a href="/#/#faq-3">Question 3</a>
<a href="#faq-1" target="_self">Question 1</a>
<a href="#faq-2" target="_self">Question 2</a>
<a href="#faq-3" target="_self">Question 3</a>
<h3 id="faq-1">Question 1</h3>
<h3 id="faq-2">Question 2</h3>
<h3 id="faq-3">Question 3</h3>
$scope.scrollTo = function (id) {
$anchorScroll(id);
}
<a href="" ng-click="scrollTo(id)">Text</a>
.run(function ($anchorScroll) {
//this will make anchorScroll scroll to the div minus 50px
$anchorScroll.yOffset = 50;
});
<a href="{{ 'my-element-id' | anchor }}">My element</a>
.filter('anchor', ['$state', function($state) {
return function(id) {
return '/#' + $state.current.url + '#' + id;
};
}])
app.directive('scrollto',
function ($anchorScroll,$location) {
return {
link: function (scope, element, attrs) {
element.click(function (e) {
e.preventDefault();
$location.hash(attrs["scrollto"]);
$anchorScroll();
});
}
};
})
<a href="" scrollTo="yourid">link</a>
app.run(function($location, $anchorScroll){
var uri = window.location.href;
if(uri.length >= 4){
var parts = uri.split('#!#');
if(parts.length > 1){
var anchor = parts[parts.length -1];
$location.hash(anchor);
$anchorScroll();
}
}
});