在移动端的页面中,我们会遇到有一部分是一直显示的,比如说菜单项,当页面初始化的时候,它处在文档流内,当页面下滑的时候,并且菜单到达顶部之后就会一直定位在顶部,并且上滑的时候,菜单又会回到文档流。
到这里大家应该会有点思路,定位在顶部不动了,那就肯定用了position: fixed;,再实现可以回到文档流,那这一块就最好使用定位布局,方便控制。下面是我根据这个来写的一个:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>移动端页面滑动,菜单到顶部之后定位在顶部</title>
<style>
* {margin: 0;padding: 0;}
.header {width: 100%;height: 100px;background: red;}
.container {width: 100%;height: 1000px;background: #ccc;}
.liveDiv {top: 0;width: 100%;height: 50px;background: green;}
.scale {transform: scale(0.5);transform-origin: 0% 0%;}
</style>
<script src="http://apps.bdimg.com/libs/jquery/1.11.3/jquery.js"></script>
</head>
<body>
<div class="header"></div>
<div class="container">
<div class="liveDiv"></div>
</div>
<script>
/*
* 菜单移动到顶部后定位在顶部
* message[菜单的id名或者class类名]
* height[菜单距离顶部的距离]
*/
function navChangeArea(message, height) {
var liveDiv = $("#" + message).length ? $("#" + message) : $("." + message);
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop < height) {
liveDiv.css("position", "relative");
} else {
liveDiv.css("position", "fixed");
}
}
$(window).bind("scroll", function() {
navChangeArea("liveDiv", 100);
});
$(window).bind("touchmove", function() {
navChangeArea("liveDiv", 100);
});
</script>
</body>
</html>
此处绿色的div块就代表上面所说的菜单,实现方式就是初始化布局使用绝对定位,这样top、left属性就设置了,并且要保证position: fixed;的时候top、left依然适用,给全局对象window绑定事件scroll、touchmove,之所以也需要touchmove事件是为了让运行起来更加流畅,不会有突兀变化的感觉。
上面的在安卓下面测试相当棒,但是在苹果下面总是在移动结束之后会有一个明显的变化,看起来很不舒服,可以扫面下面二维码的进行查看:
经过查看之后,好像是苹果不支持touchmove事件,只会在滑动结束的时候才会进行判断,这就比较尴尬了。。。。。。
但是经过查找资料,发现了position: sticky;,这个是苹果自己出的,并且已经交由w3c审核了,现在进苹果支持这个属性,其他的安卓端的浏览器暂时不支持(PC端谷歌浏览器已经支持)。
position: sticky;的支持性如下:
那position: sticky;是用来干嘛的呢,简单的说它类似于position: relative;和position: fixed;的合体,当目标区域在屏幕中可见时,它的行为就像position: relative;, 而当页面滚动时,目标区域要超出屏幕的时候,它的表现就像position: fixed;。多么神奇的一个功能。
那这样的话,我们就可以在安卓浏览器的时候调用上面的js方法,在苹果浏览器中的时候调用position: sticky;的属性,这样的话就牵扯到判断浏览器是安卓还是苹果的:
if(/android/i.test(navigator.userAgent)){
// 我是安卓浏览器
}
if(/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)){
// 我是苹果浏览器
}
这样的话就有如下的代码了:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>positionSticky</title>
<style>
* {margin: 0;padding: 0;}
.header {width: 100%;height: 100px;background: red;}
.container {width: 100%;height: 1000px;background: #ccc;}
.liveDiv {top: 0;width: 100%;height: 50px;background: green;}
.sticky {position: -webkit-sticky;position: -moz-sticky;position: -ms-sticky;position: -o-sticky;position: sticky;}
.scale {transform: scale(0.5);transform-origin: 0% 0%;}
</style>
<script src="http://apps.bdimg.com/libs/jquery/1.11.3/jquery.js"></script>
</head>
<body>
<div class="header"></div>
<div class="container">
<div class="liveDiv"></div>
</div>
<script>
/*
* 菜单移动到顶部后定位在顶部
* message[菜单的id名或者class类名]
* height[菜单距离顶部的距离]
*/
function navChangeArea(message, height) {
var liveDiv = $("#" + message).length ? $("#" + message) : $("." + message);
if(/android/i.test(navigator.userAgent)){
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop < height) {
liveDiv.css("position", "relative");
} else {
liveDiv.css("position", "fixed");
}
}
if(/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)){
liveDiv.addClass("sticky");
}
}
$(window).bind("scroll", function() {
navChangeArea("liveDiv", 100);
});
$(window).bind("touchmove", function() {
navChangeArea("liveDiv", 100);
});
</script>
</body>
</html>
这样的话在安卓和苹果下都完美的兼容了,依然给个二维码,大家体验一下吧。