壹 ❀ 引
公司新項目開發中,首頁要做個樓層導航效果(如下圖),要求能點擊圖標對應跳到樓層即可,因為不需要跳轉過度動畫,也要求最好別用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
配置在上方,這里我就不再貼一遍代碼了。
另外,今天是七夕,公司同事老早就留光了,其實我知道他們一大部分都是單身狗,非得裝的自己有約一樣。
那么問題來了,為什么我要留下寫博客?