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>