vue组件化
原理:检查是否兼容position: sticky ,若兼容就使用,若不兼容则在watch监听高度(若高度是变化的)或者在mounted中直接调用(高度不变)
1 <template> 2 <div class="header_sticky"> 3 <slot></slot> 4 </div> 5 </template> 6 <script> 7 export default { 8 name: 'stickyHeader', 9 computed: { 10 randomId: function(){ 11 return 'randomId_' + Number(Math.random().toString().substr(3,3) + Date.now()).toString(36); 12 }, 13 targetElement_: function() { 14 return this.$el 15 } 16 }, 17 methods: { 18 // |-> css: 用于替换的css样式; (一般用默认的) 19 sticky_(css='sticky_') { 20 if (CSS.supports('position', 'sticky') || CSS.supports('position', '-webkit-sticky')) { 21 console.log('>>>>>>>>> sticky is supported') 22 } else { 23 let newNodeTop; 24 let header = this.targetElement_; 25 if(document.getElementById(this.randomId)) { 26 newNodeTop = document.getElementById(this.randomId); 27 }else{ 28 newNodeTop = document.createElement("div"); 29 newNodeTop.id = this.randomId; 30 header.parentNode.insertBefore(newNodeTop, header); 31 header.classList.add(css); 32 } 33 34 setTimeout(() => { 35 let height = header.offsetHeight + 1; //高度 + 1 以防有小数点 36 newNodeTop.style.height = height + 'px'; 37 }, 0) 38 } 39 }, 40 } 41 } 42 </script>
/*********** !要用异步获取高度 */
css
1 .header_sticky { 2 width: 100%; 3 position: sticky; 4 position: -webkit-sticky; 5 top: 0; 6 z-index: 100; 7 transition: height 1s; 8 -moz-transition: height 1s; 9 -webkit-transition: height 1s; 10 -o-transition: height 1s; 11 } 12 13 .sticky_ { 14 width: 100%; 15 position: fixed; 16 position: -webkit-fixed; 17 top: 0; 18 z-index: 100; 19 }
在watch中监听高度变化
1 watch: { 2 oldToNew(newVal, oldVal) { 3 if(newVal.length !== oldVal.length) { 4 this.$refs.sticky_.sticky_() 5 } 6 } 7 }
在mounted中获取高度变化
this.$refs.sticky_.sticky_()
<使用>
html
<sticky-header ref="sticky_"> <!-- contents --> </sticky-header>