position:sticky的兼容性尝试
问题
在这⾥主要介绍下关于css3草案的position:sticky属性的兼容。
⽬前前端的h5有个需求,就是“当页⾯上的若⼲个标题被拖动到视⼝的顶部时,则显⽰⼀个被定位到视⼝的顶部的tab标签,可对这个tab标签进⾏点击导航,并在某个特殊的情况下隐藏”。最简单粗暴的做法就是针对document.body做scroll侦听,在函数中遍历所有的标题并计算出getBoundingClientRect计算出距离适⼝的顶部距离,决定是否显⽰tab栏或者活动标签,但是在这⾥可能会出现⼀些性能问题:
+ 在浏览器端和安卓设备上,scroll事件连续触发,如果在侦听函数中做过于复杂的判断,肯定会暂时阻塞ui(主)线程的渲染,造成卡顿+ 每次在侦听函数中都执⾏⼀次getBoundingClientRect函数,都会导致ui线程刷新渲染队列,进⾏⼀次layout和repaint,有可能造成卡顿
+ 在ios设备中,scroll事件在上下滑动的过程中js不会连续执⾏,只在滑动结束的时刻执⾏⼀次,并且不⽀持左右滑动事件的触发
针对上述问题进⾏修复,其实并不困难:
+ 针对scroll做throttle节流,避免每次滑动都执⾏,可以设置时间间隔,如50ms
+ 在侦听函数中计算元素的layout属性,可⽤setTimeout在定时器队列尾插⼊任务,异步渲染
+ ios设备实现了⼀个属性-position:sticky,可以不⽤js来完成粘性布局
深⼊
针对sticky布局的兼容性,我们很容易兼容⼤多数移动端浏览器。在pc和安卓的chrome中并未实现该属性,⽽在pc和iOS 的safari中全部兼容该属性,因此针对iOS可以单独使⽤sticky完成兼容。
sticky布局有着⼏个条件:
+ 元素并不会脱离⽂档流,当元素被粘在视⼝的顶部时,原来在⽂档流中的位置仍然占据,这点类似relative定位
+ 元素相对于其最近可滚动的祖先元素“粘性定位”,如果其祖先元素都不能滚动,则相对于适⼝定位
+ 元素最近的祖先元素overflow设置为⾮默认值visible时,则元素相对于该祖先元素进⾏sticky定位。若最近的祖先元素设置为overflow:hidden,则元素不会sticky定位
因此解决ios的代码可以这样:
/
/ sticky类为粘性布局的样式设置
if (gtIOS6) {
// ⼤于等于iOS6版本使⽤sticky
$tab.addClass('sticky');
}
.sticky {
position: -webkit-sticky;
position: sticky;
top: 0;
}
⽰例代码:
<!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="apps.bdimg/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(/st(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>position标签属性
</body>
</html>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。