angularjs中使用锚点,angular路由导致锚点失效的两种解决方案
壹 ❀ 引
公司新项目开发中,首页要做个楼层导航效果(如下图),要求能点击图标对应跳到楼层即可,因为不需要跳转过度动画,也要求最好别用JQ,想着原生js操作dom计算top的兼容性,想着用锚点实现算了,结果一番波折,也是弄的我头大,所以这里就做个记录吧。

我们都知道锚点一般做法是通过a标签结合目标id来做,结果有趣的事情发生了,我在项目中写的锚点就是不生效。
<a href="#Top">click</a>
<div id="Top"></div>
特意去写了个小demo验证了下,跳转也没问题,这样我就慌了,我也是做了2年开发的人了,锚点都玩不好了?
打开百度,输入angularjs使用锚点,得到最多的回答就是使用$anchorScroll,所以我先决定先了解此方法。
贰 ❀ 尝试使用$anchorScroll
$anchorScroll是angularjs自带的模块,当被调用时,页面会滚动到与元素相关联的指定的hash处,通过$location.hash(‘要跳转的锚点’)来设置你要跳转的锚点,再通过一个条件来触发$anchorScroll就ok了,这里直接附上简单的代码:
<div ng-controller="myCtrl">
<divid="top" style="height:1000px">我是顶部</div>
<a ng-click="toTop()">click</a>
</div>
angular.module('myApp', [])
.controller('myCtrl', ['$scope', '$location', '$anchorScroll',
function ($scope, $location, $anchorScroll) {
$scope.toTop = function () {
//设置你要跳转的锚点
$location.hash('top');
//调用$anchorScroll
$anchorScroll();
};
}
]);
单独测试完全没问题,于是我引入到了我的项目中,锚点跳转没有问题,但不知道为啥报了个错。

我猜测可能是angularjs版本问题,但就算不报错,我觉得$anchorScroll有点麻烦,毕竟我的楼层有好几个图标,得绑定好几次点击事件,虽然我能将hash中锚点设置成一个变量,这样只用写一个函数让调用时传递不同参数做hash,但始终觉得这样玩一个锚点太累了。
就在我思考还有没有别的解决方案时,我的目光停留在了浏览器地址栏上,我发现这个地址是不是有点不太对?
我项目锚点跳转后的地址:

正常锚点跳转后的地址:

怎么正常的是#/锚点,我的却是#!#锚点,脑中灵光一闪,这才发现引发问题所在,是angularjs的路由所引发的问题。
我给我的小demo也引入了angularjs路由,刷新页面,果不其然,地址栏自动就变成了带!的样子:

我们在定义路由页面跳转时也是以#开头,不巧的是锚点也是#开头,引入angular路由后,由于路由的影响,angular把设置的锚点也当成路由页面跳转了,锚点很明显识别不了!,所以这才失效了。
那么怎么让去除掉路由页的#!呢,于是我成功定位到了$locationProvider。
叁 ❀ 使用$locationProvider
通过$locationProvider页面介绍了解到(点击查看官方文档),路由哈希默认前缀就是!,而我们可以通过$locationProvider.hashPrefix()方法来修改默认hash前缀,于是我给我的项目添加了一段配置:
angular.module('myApp', [])
.controller('myCtrl', [, function () {
}]).config([
"$locationProvider",
function ($locationProvider) {
$locationProvider.hashPrefix("");
$locationProvider.html5Mode({
rewriteLinks: false
});
}
]);
再进入项目测试我之前的锚点,完全没问题了:

肆 ❀ 总结
一个小小的锚点,至少今天是把我给整懵了,其实说到底,还是因为angularjs使用不够深层次的问题,对于hash等配置的不敏感,在找问题时出发点就错了。当然,还是总结出了2种解决方案:
第一种,使用$anchorScroll
我不知道其他人有没有发现,其实只要注入了$anchorScroll服务,不用写任何触发事件,锚点就可以正常使用了,哪怕是引用了路由的情况。
<div id="top1" style="height:500px">我是顶部1</div>
<div id="top2" style="height:500px">我是顶部2</div>
<div id="top3" style="height:500px">我是顶部3</div>
<a href="#top1">click</a>
<a href="#top2">click</a>
<a href="#top3">click</a>
angular.module('myApp', ['ui.router'])
.controller('myCtrl', ['$anchorScroll', function ($anchorScroll) {
}]);
这里我只是注入了$anchorScroll服务,未定义任何点击事件,而且也引入了angularui的路由,比较神奇的是,锚点一切正常,当然这完全是我瞎猫碰老鼠,碰巧发现的。
第二种,使用$locationProvider
配置在上方,这里我就不再贴一遍代码了。
另外,今天是七夕,公司同事老早就留光了,其实我知道他们一大部分都是单身狗,非得装的自己有约一样。

那么问题来了,为什么我要留下写博客?
angularjs中使用锚点,angular路由导致锚点失效的两种解决方案的更多相关文章
- angularjs中向html页面添加内容节点元素代码段的两种方法
第一种方式:原生JS向html页面添加内容节点元素代码段: <!DOCTYPE html> <html> <head> <meta charset=" ...
- PHP中实现MySQL嵌套事务的两种解决方案
PHP中实现MySQL嵌套事务的两种解决方案 一.问题起源 在MySQL的官方文档中有明确的说明不支持嵌套事务: Transactions cannot be nested. This is a co ...
- SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法
软件152 尹以操 首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33# 这篇文章中讲的是spring中使用spring data jpa,使用了xml ...
- vue 路由传参 params 与 query两种方式的区别
初学vue的时候,不知道如何在方法中跳转界面并传参,百度过后,了解到两种方式,params 与 query.然后,错误就这么来了: router文件下index.js里面,是这么定义路由的: { p ...
- laravel5.5框架中视图间如何共享数据?视图间共享数据的两种方法
laravel框架中视图间共享数据有两种,一种是用视图门面share()方法实现,另一种是用视图门面composer() 方法实现,那么,两种方法的实现究竟是怎样的呢?让我们来看一看接下来的文章内容. ...
- Java中的策略模式,完成一个简单地购物车,两种付款策略实例教程
策略模式是一种行为模式.用于某一个具体的项目有多个可供选择的算法策略,客户端在其运行时根据不同需求决定使用某一具体算法策略. 策略模式也被称作政策模式.实现过程为,首先定义不同的算法策略,然后客户端把 ...
- AngularJs中ng-controller下的函数在调用时为什么会执行两次?
最近在学习AngularJs的过程中,自己做了个demo,但程序运行后却发现有个地方运行不对劲,纠结了半天,也问了,也查了,但是没有一个满意的答案,所以特地贴出来,请教各位大神(先说声谢谢了!).为了 ...
- vue路由跳转传参的两种方法
路由跳转: this.$router.push({ name: '工单列表', params: {p_camera_dev_name: 'xxx'} }); 使二级菜单呈点击状态: $('[index ...
- Vue路由实现页面跳转的两种方式(router-link和JS)
Vue.js 路由可以通过不同的 URL 访问不同的内容,实现多视图的单页 Web 应用 1.通过 <router-link> 实现 <router-link> 组件用于设置一 ...
随机推荐
- 【西北师大-2108Java】第十次作业成绩汇总
[西北师大-2108Java]第十次作业成绩汇总 作业题目 面向对象程序设计(JAVA) 第12周学习指导及要求 实验目的与要求 (1)掌握Vetor.Stack.Hashtable三个类的用途及常用 ...
- JSON对象转JAVA对象--com.alibaba.fastjson.JSONObject
打印结果:
- Codeforces Round #590 D. Distinct Characters Queries
CF上给的标签是数据结构.但给的题解里的方法是很巧的暴力,用vector<set>维护每个字母出现的下标,每次修改加下标,擦下标.每次询问对每个字母分别lower_bound查找区间内是否 ...
- IT兄弟连 HTML5教程 HTML5文字版面和编辑标签 HTML基础标签
指引 网页中的信息主要是以文本为主的,可以通过字体.大小.颜色.底纹.边框等来设置文本的属性.文字版面的编辑包括文本标签和格式标签两种,在浏览器中显示的文字内容和格式都要在<body>标记 ...
- PHP实现微信提现(企业付款到零钱)
怎么开通企业付款到零钱? 有的商户号的产品中心是没有这个功能的,不过,该功能的pid(product id)是5,只要随便进去某一个产品,在地址栏把pid改为5. 即可进入该功能页面,进行开通,不过要 ...
- React 从入门到进阶之路(一)
在开始 React 学习之前我们先进入官网 https://react.docschina.org/ 看看官方对 React 的解释:React 是用于构建用户界面的JavaScript 库.我们只需 ...
- Java题库——Chapter6 一维数组
1)What is the representation of the third element in an array called a? 1) _______ A)a(3) B) a(2) C) ...
- jvm虚拟机笔记<五> 编译期优化
JVM的编译器可以分为三个编译器: 1.前端编译器:把.java转变为.class的过程.如Sun的Javac.Eclipse JDT中的增量式编译器(ECJ). 2.JIT编译器:把字节码转变为机器 ...
- 爬虫最新的库requests-html库总结
requests-html是比较新的爬虫库,作者和requests是同一个作者 一.安装依赖 pip install requests-html 我们可以在安装的时候看到他安装了lxml,reuqes ...
- 7天教你精通变大神,学CAD关键还要掌握方法,纯干货新手要看
接触CAD初期是“痛苦”的,“煎熬”的,也是充满“成就”的. 痛苦是初学者怎么都不懂,需要学习的东西很多,整个过程是有些痛苦的. 煎熬也是每个求学阶段都会遇到的状态,眼睛会了,手不会,这个状态很难受. ...