zoukankan      html  css  js  c++  java
  • 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

    配置在上方,这里我就不再贴一遍代码了。

    另外,今天是七夕,公司同事老早就留光了,其实我知道他们一大部分都是单身狗,非得装的自己有约一样。

    那么问题来了,为什么我要留下写博客?

  • 相关阅读:
    区别@ControllerAdvice 和@RestControllerAdvice
    Cannot determine embedded database driver class for database type NONE
    使用HttpClient 发送 GET、POST、PUT、Delete请求及文件上传
    Markdown语法笔记
    Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
    Mysql 查看连接数,状态 最大并发数(赞)
    OncePerRequestFilter的作用
    java连接MySql数据库 zeroDateTimeBehavior
    Intellij IDEA 安装lombok及使用详解
    ps -ef |grep xxx 输出的具体含义
  • 原文地址:https://www.cnblogs.com/echolun/p/11316548.html
Copyright © 2011-2022 走看看