window.history
與document.referer
)在作頁面回退功能的時候接觸到瀏覽器歷史記錄相關的問題特別頭疼。(貌似咱們大前端無法跟蹤用戶的行爲?應該是本身瞭解的太少的緣由,求教啊!)研究了window.history
對象也沒有找到解決方案。另外還了解了document
對象的referer
方法(用來獲取打開當前文檔的文檔的URI)。javascript
先來講說window.history
對象,返回進行瀏覽記錄的操做的方法有3個,分別是:css
window.history.go(n);
根據n的值進行前進回退n步的操做。其中-1和1與下面的兩個方法實現的效果同樣。window.history.back();
與瀏覽器的後退按鈕相同。window.history.forward();
與瀏覽器的前進按鈕相同。html
ps:window.location.replace()
方法進行頁面跳轉時會覆蓋當前頁面在瀏覽器歷史中的記錄。
ps2: h5在history API中新增了向瀏覽歷史添加一條狀態的方法,名爲window.history.pushState(state, title, url)
。各瀏覽器支持良好。它的效果與window.location = "#foo"
的操做至關,這兩種行爲都會建立和激活另外一個和當前頁面有關的歷史紀錄。可是==pushState()有其餘優點==:
- 新URL能夠是當前URL同源下的任意地址。相反的,設置window.location會讓你保持在相同頁面,除非你只修改hash.
- 若是沒必要要,你能夠不改變URL,相反的,將window.location設定爲「#foo」;只會建立一個新的歷史紀錄,若是當前hash不爲#foo.
- 你能夠關聯任意的數據到你的新歷史紀錄中。使用基於hash的方法,你須要將全部相關 的數據編碼爲一個短字符串。
須要注意的是:==pushState()方法毫不會致使hashchange 事件被激活,即便新的URL和舊的只在hash上有區別。==前端
操做示例:java
var state = { 'page_id': 1, 'user_id': 5 }; var title = 'Hello World'; var url = 'hello-world.html'; history.pushState(state, title, url);
其餘參考博客css3
ps3:
document.referrer
返回載入當前文檔的文檔的URI。若是當前文檔是經過地址欄直接輸入的或者書籤欄進入的,則返回一個空字符串。瀏覽器
原先對回退按鈕的要求是:微信
當前頁的上一頁爲空或者不是從首頁或者其餘與咱們公司相關的頁面進來的,回到首頁或者回到它的上一頁級頁面。(這個上一級頁面坑人了,主要是一些頁面的地址欄須要帶參,不用
history
API的方法或者document.referrer
貌似都不行)wordpress
看看其餘公司的h5頁面的回退方案佈局
淘寶h5頁面:
- ==場景一==:==商品頁==點擊加入購物車(未登陸狀態)--進入-->>==登陸頁==--點擊瀏覽器返回按鈕-->>==商品頁==--點擊瀏覽器返回按鈕-->>==商品頁==;
- ==場景二==:==商品頁==點擊購物車(未登陸狀態)--進入-->>==購物車==--跳轉-->>==登陸頁==--跳轉-->>==購物車==--點擊返回按鈕-->>==購物車==--再點-->>==商品頁==
- 總結:使用了相似
window.location.replace();
的方法。覆蓋了登陸頁的記錄。而後經過history.back();
返回。
京東h5頁面:同淘寶。
最後採用的方案:document.referrer
+history.back();
+window.location.replace();
登陸後在瀏覽器歷史記錄中的排位是
section 第三條記錄 詳情頁以前的頁面(回退按鈕返回的頁面) section 第二條記錄 詳情頁(登陸後展現的頁面) section 最新的記錄 登陸頁(瀏覽器前進按鈕返回的頁面)
至此, 感受走火入魔了。這個問題是否真的有必要深刻解決呢?感受有點鑽牛角尖。接下來準備根據history的新的API寫一個單頁應用的demo,就over。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>css content 換行demo</title> </head> <style> html, body { margin: 0; padding: 0; } dot { display: inline-block; height: 1em; line-height: 1; vertical-align: -.25em; overflow: hidden; } dot::before { display: block; content: '.\A..\A...'; white-space: pre-wrap; animation: dot 3s infinite step-start both; } @keyframes dot { 0% {transform: translateY(0em);} 33% { transform: translateY(-1em); } 66% { transform: translateY(-2em); } } </style> <body> <a href="javascript:" class="grebtn">訂單提交中<dot></dot></a> </body> </html>
這個是在寫公司h5頁面的時候遇到的,由於頁面的側邊欄有須要滾動的內容,而這個時候若是整個屏幕也發生滾動的話體驗感特差,而後我又上各大論壇以及Google扒了一下,如今已基本解決這個問題了。
首先附上個人js代碼
var $solveFix = { scrollTop:undefined, bodyWidth:undefined, offFix: function (){ this['scrollTop'] = $('body').scrollTop(); this['bodyWidth'] = $('body').width(); //禁止屏幕滾動,點擊‘對比中的房源’時恢復滾動 $('body, html').css({ 'position': 'fixed', 'top': - this['scrollTop'], 'left': '50%', 'margin-left': - this['bodyWidth'] / 2, 'z-index': 1 }); }, onFix: function (){ $('body, html').css({'position': 'static', 'top':0, 'margin': '0 auto'}).scrollTop(this['scrollTop']); } }
以上代碼採用的是fix定位的方案使==整個body,html浮起來,這樣就使得整個頁面不會發生上下的滾動,而內部的子元素依然能夠自由地上下滑==。然而,在後面的實踐中,發現這個方案有個不足之處:
在禁止滾動的時候,body的可視部分若是有輸入框,則在它獲取焦點,彈出虛擬鍵盤時,整個頁面都會隨之上滑。這個問題待解決,目前只能儘可能避免這種佈局。
ps: 在查閱文檔和各大論壇的時候有人提出用
body, html{overflow:hidden;}
的方案,可是在微信端不起做用。
首先貼上個人js代碼(也能夠用css的媒體查詢來實現)
var root = document.getElementsByTagName('html')[0], NATIVE_W = 640; function updateSize(){ var w = window.innerWidth; if(w > 500) { w = 500; }else if(w < 320) { w = 320; } var cw = w / (NATIVE_W / 27.30666666666667); root.style.fontSize = cw + 'px'; } window.onload = function(){ updateSize(); document.getElementsByTagName('body')[0].style.display = 'block'; } window.onresize = function(){ updateSize(); }
核心是==保持不一樣寬度的設備下,寬度與根節點font-size
的比例保持一致。== 在此基礎上,加了最大、最小寬度的限制。