vue填坑之回到頂部:
阿新 • • 發佈:2019-02-11
vue來實現回到頂部程式碼(參考慕課網):
<div id='goTop' @click='goTop' v-show = 'toTop'>
<img src="./goTop.png">
</div>
let stop = false; // 全域性變數,坑處
let timer = null; // 全域性變數,坑處
mounted() { this.$nextTick(function () { window.addEventListener('scroll', this.needToTop); //滾動事件監聽 }); }, methods: { goTop: function() { // 回到頂部方法 clearInterval(timer); timer = setInterval(function() { console.log('不妙'); let curHeight = document.documentElement.scrollTop || document.body.scrollTop; // 得到當前高度 var now = curHeight; var speed = (0 - now) / 7; // 隨著高度減速 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); console.log(`當前的高度應該是:` + curHeight); console.log('我是零你也那我沒辦法'); if (curHeight === 0) { //當前高度為零,停止這次計時器 clearInterval(timer); // C1 } document.documentElement.scrollTop = curHeight + speed; //直接給高度賦值,會呼叫needtotop方法 document.body.scrollTop = curHeight + speed; //谷歌的 stop = false; // A console.log('回到頂部一次'); }, 30); }, needToTop: function() { let curHeight = document.documentElement.scrollTop || document.body.scrollTop; let viewHeight = document.documentElement.clientHeight; if (curHeight > viewHeight + 100) { this.toTop = true; //賦值是為了按鈕的v-show='toTop' } else { this.toTop = false; } if (stop) { //STOP clearInterval(timer); //C2 console.log('我沒了'); } stop = true; //B console.log('執行了一次'); } }
從點選回到頂部開始,正常的執行順序:
ABABABABABABAB......C1
如果在途中先停下來:
ABAB.....AB.....(此時stop為true,但是你突然動了滾條,-->)............STOP.........C2
好,我們逐一地把timer和stop內化成vue元件裡的data:
data() {
return {
dataTimer: null
};
},
把方法裡的所有的timer改成this.dataTimer;
結果即使到了最頂端,竟然還會出現:
這是為什麼????這是為什麼????這是為什麼????這是為什麼????這是為什麼????這是為什麼????
我們接著把stop內化成vue元件裡的data
data() {
return {
dataStop: false
};
},
再把以上程式碼的stop全部換成dataStop,
問題更嚴重了:直接只滾動了一次
居然只執行了一次?????,
填坑:然後我在watch裡面觀察了這個stop,結果是,沒有執行回撥函式:
watch: { dataStop: { handler: function() { console.log('我變了' + this.dataStop); } }
結論:
在計時器觸發的時候,datastop應該是true的,當計時器又去執行滾動條監聽事件的時候,雖然在執行之前已經改了this.datastop為false,但是vue裡我們 並沒有真正的改變過datastop,整個生命週期就是:vue方法呼叫vue方法,直到vue方法跑完,datastop都沒有改動過