2016年11月总结
11月折腾/研究的料
- 浏览记录相关(
window.history
与document.referer
) - css3相关(animate做loading动画)
- 微信端滚动穿透问题
- 移动端宽度自适应
- 页面布局和书写样式能力提升
浏览器历史记录相关
在做页面回退功能的时候接触到浏览器历史记录相关的问题特别头疼。(貌似我们大前端没法跟踪用户的行为?应该是自己了解的太少的原因,求教啊!)研究了window.history
对象也没有找到解决方案。另外还了解了document
对象的referer
方法(用来获取打开当前文档的文档的URI)。
先来说说window.history
对象,返回进行浏览记录的操作的方法有3个,分别是:
window.history.go(n);
根据n的值进行前进回退n步的操作。其中-1和1与下面的两个方法实现的效果一样。window.history.back();
与浏览器的后退按钮相同。window.history.forward();
与浏览器的前进按钮相同。
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上有区别。
操作示例:
var state = { 'page_id': 1, 'user_id': 5 };
var title = 'Hello World';
var url = 'hello-world.html';
history.pushState(state, title, url);
ps3:
document.referrer
返回载入当前文档的文档的URI。如果当前文档是通过地址栏直接输入的或者书签栏进入的,则返回一个空字符串。
原先对回退按钮的要求是:
当前页的上一页为空或者不是从首页或者其他与我们公司相关的页面进来的,回到首页或者回到它的上一页级页面。(这个上一级页面坑人了,主要是一些页面的地址栏需要带参,不用
history
API的方法或者document.referrer
貌似都不行)
看看其他公司的h5页面的回退方案
- **家h5页面:直接从地址栏进入带回退按钮的页面,则隐藏回退按钮,页面上可以点击“首页”按钮来回到首页。
- 淘宝h5页面:
- 场景一:商品页点击加入购物车(未登录状态)--进入-->>登录页--点击浏览器返回按钮-->>商品页--点击浏览器返回按钮-->>商品页;
- 场景二:商品页点击购物车(未登录状态)--进入-->>购物车--跳转-->>登录页--跳转-->>购物车--点击返回按钮-->>购物车--再点-->>商品页
- 总结:使用了类似
window.location.replace();
的方法。覆盖了登录页的记录。然后通过history.back();
返回。
- 京东h5页面:同淘宝。
最后采用的方案:document.referrer
+history.back();
+window.location.replace();
- 判断载入当前页的文档的域名是否相同;
- 流程:搜索页--进入-->>详情页--进入-->>登录页--返回-->>详情页--返回-->>搜索页;
登录后在浏览器历史记录中的排位是
section 第三条记录
详情页之前的页面(回退按钮返回的页面)
section 第二条记录
详情页(登录后展示的页面)
section 最新的记录
登录页(浏览器前进按钮返回的页面)
至此, 感觉走火入魔了。这个问题是否真的有必要深入解决呢?感觉有点钻牛角尖。接下来准备根据history的新的API写一个单页应用的demo,就over。
css3 利用content+animate实现loading动画
<!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;}
的方案,但是在微信端不起作用。
移动端宽度基于rem单位的自适应布局
首先贴上我的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
的比例保持一致。
在此基础上,加了最大、最小宽度的限制。