複製就可以用啦 <template> <div id="app"> <div class="box box1" :style="box1Style" ref="box1" > <div class="dargbtn" @mousedown="box1ButtonDown">點此拖拽1</div> <div class="delay-box"> <span v-for="(item, index) in testData1" :key="index" :data-testdata="testFun('box1')" >{{item.value}}</span> </div> </div> <div class="box box2" :style="box2Style" ref="box2"> <div class="dargbtn" @mousedown="box2ButtonDown">點此拖拽2</div> <div class="delay-box"> <span v-for="(item, index) in testData2" :key="index" :data-testdata="testFun('box2')">{{item.value}}</span> </div> </div> </div> </template> <script> export default { name: "index", data () { return { // 測試數據 testData1: [ {value: '1'}, {value: '2'}, {value: '3'}, {value: '4'}, {value: '5'}, {value: '6'}, {value: '7'}, {value: '9'}, {value: '10'} ], testData2: [ {value: '1'}, {value: '2'}, {value: '3'}, {value: '4'}, {value: '5'}, {value: '6'}, {value: '7'}, {value: '9'}, {value: '10'} ], // 1 box1X: 0, box1Y: 0, box1L: 0, box1T: 0, box1CurrentX: 0, box1CurrentY: 0, // 2 box2X: 0, box2Y: 0, box2L: 0, box2T: 0, box2CurrentX: 0, box2CurrentY: 100 } }, computed: { box1Style() { return { top: this.box1CurrentY + 'px', left: this.box1CurrentX + 'px' }; }, box2Style() { return { top: '100px', left: '0px' }; } }, methods: { box1Start(e) { let dv = this.$refs.box1; this.box1X = e.clientX; this.box1Y = e.clientY; this.box1L = dv.offsetLeft; this.box1T = dv.offsetTop; }, box1Move(e) { console.log('box1 move'); let nx = e.clientX; let ny = e.clientY; let nl = nx - (this.box1X - this.box1L); let nt = ny - (this.box1Y - this.box1T); // 代碼關鍵處 this.box1CurrentX = nl; this.box1CurrentY = nt; }, box1End(e) { window.removeEventListener('mousemove', this.box1Move); window.removeEventListener('mouseup', this.box1End); }, box1ButtonDown(e) { this.box1Start(e); window.addEventListener('mousemove', this.box1Move); window.addEventListener('mouseup', this.box1End); }, box2Start(e) { // 獲取元素 let dv = this.$refs.box2; // 獲取x座標和y座標 this.box2X = e.clientX; this.box2Y = e.clientY; // 獲取左部和頂部的偏移量 this.box2L = dv.offsetLeft; this.box2T = dv.offsetTop; }, box2Move(e) { console.log('box2 move'); let nx = e.clientX; let ny = e.clientY; let nl = nx - (this.box2X - this.box2L); let nt = ny - (this.box2Y - this.box2T); // 代碼關鍵處 this.box2CurrentX = nl; this.box2CurrentY = nt; let legendBox = this.$refs.box2; legendBox.style.left = nl + 'px'; legendBox.style.top = nt + 'px'; }, box2End(e) { window.removeEventListener('mousemove', this.box2Move); window.removeEventListener('mouseup', this.box2End); }, box2ButtonDown(e) { this.box2Start(e); window.addEventListener('mousemove', this.box2Move); window.addEventListener('mouseup', this.box2End); }, testFun(name) { // 如果此時加入長時間處理代碼,就會降低mousemove幀數率 console.time(name + '-delay'); for (let i = 0; i < 10240000; i++) {} console.timeEnd(name + '-delay'); } } } </script> <style> *::selection { background: none; } .box { position: fixed; z-index: 100; width: 200px; height: 80px; } .dargbtn { margin: 15px; color: #222222; background: #eee; cursor: pointer; } .box1 { background: #c0c; } .box2 { background: #0cc; } </style>
<!-- <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <title> 頁面名稱 </title> <style type="text/css"> html,body { height: 100%; margin: 0; } #d { position: absolute; left: 200px; top: 200px; width: 100px; height: 100px; background-color: #999; transform: translate(0px,0px); transition: transform; } </style> </head> <body> <div id="d"></div> <script type="text/javascript"> document.onmousemove = function (e) { e = e||window.event; var x = 0.5-e.clientX/document.body.offsetWidth; var y = 0.5-e.clientY/document.body.offsetHeight; document.getElementById("d").style.transform = "translate("+x*100+"px,"+y*100+"px)"; }; </script> </body> </html> --> <!--<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>無標題文檔</title> <script src="jquery-1.3.2.min.js" ></script> <script> $(function(){ $("#imgframe").mousemove(function(e){ $(this).css("background","url(https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1548896602,3212907422&fm=26&gp=0.jpg)"+ e.pageX +"px "+ e.pageY+"px no-repeat") }) }) // https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=167219548,1510840028&fm=26&gp=0.jpg </script> <style> #imgframe{ background:url(https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1548896602,3212907422&fm=26&gp=0.jpg) 0 0 no-repeat; width:400px; height:400px; position:absolute; left:0; top:0;} </style> </head> <body> <div id="imgframe" > </div> </body> </html>--> <!--<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>拖拽效果-js</title> <link rel="stylesheet" href=""> <style type="text/css"> body { overflow: hidden; } * { margin: 0; padding: 0; } .container { position: absolute; left: 0; top: 0; width: 200px; height: 200px; margin: 200px; background: red; } </style> </head> <body> <div class="container"></div> <script type="text/javascript"> function drap(obj) { obj.addEventListener('mousedown', start); function start(event) { // 鼠標左鍵 if (event.button == 0) { // getComputedStyle(obj)['margin-left'] return XXpx需要轉成整型 // 如果有obj有margin值而不加這個數組拖拽會出現位置偏移 offsetX = event.pageX - obj.offsetLeft + parseInt(getComputedStyle(obj)['margin-left']); offsetY = event.pageY - obj.offsetTop + parseInt(getComputedStyle(obj)['margin-top']); // 綁定事件,同樣unbind解綁定,此效果的實現最後必須要解綁定,否則鼠標鬆開後拖拽效果依然存在 //movemove事件必須綁定到$(document)上,鼠標移動是在整個屏幕上的 document.addEventListener('mousemove', move); //此處的$(document)可以改爲obj document.addEventListener('mouseup', stop); } return false;//阻止默認事件或冒泡 } function move(event) { obj.style.left = (event.pageX - offsetX) + 'px'; obj.style.top = (event.pageY - offsetY) + 'px'; return false;//阻止默認事件或冒泡 } function stop(envet) { document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', stop); } } var obj = document.getElementsByClassName('container')[0]; drap(obj); </script> </body> </html>--> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue中使用MouseMove事件 獲取鼠標座標頻率降低或事件卡頓</title> <script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script> </head> <body> <header> <h1>Vue中使用MouseMove事件 獲取鼠標座標頻率降低或事件卡頓</h1> <p>box1卡頓,box2正常</p> <pre> <h3><a href="https://cn.vuejs.org/v2/guide/computed.html#計算屬性緩存-vs-方法">#計算屬性緩存 vs 方法</a></h3> 你可能已經注意到我們可以通過在表達式中調用方法來達到同樣的效果: <p>Reversed message: "{{ reversedMessage() }}"</p> // 在組件中 methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } } 我們可以將同一函數定義爲一個方法而不是一個計算屬性。兩種方式的最終結果確實是完全相同的。然而,不同的是計算屬性是基於它們的依賴進行緩存的。只在相關依賴發生改變時它們纔會重新求值。這就意味着只要 message 還沒有發生改變,多次訪問 reversedMessage 計算屬性會立即返回之前的計算結果,而不必再次執行函數。 這也同樣意味着下面的計算屬性將不再更新,因爲 Date.now() 不是響應式依賴: computed: { now: function () { return Date.now() } } 相比之下,每當觸發重新渲染時,調用方法將總會再次執行函數。 我們爲什麼需要緩存?假設我們有一個性能開銷比較大的計算屬性 A,它需要遍歷一個巨大的數組並做大量的計算。然後我們可能有其他的計算屬性依賴於 A 。如果沒有緩存,我們將不可避免的多次執行 A 的 getter!如果你不希望有緩存,請用方法來替代。 </pre> <p> 總結:如果能用計算屬性滿足需求優先使用,如果使用方法需注意方法執行時長 </p> </header> <div id="app"> <div class="box box1" :style="box1Style" ref="box1" > <div class="dargbtn" @mousedown="box1ButtonDown">點此拖拽1</div> <div class="delay-box"> <span v-for="(item, index) in testData1" :key="index" :data-testdata="testFun('box1')" >{{item.value}}</span> </div> </div> <!--:data-testdata="testFun('box1')"--> <div class="box box2" :style="box2Style" ref="box2" > <div class="dargbtn" @mousedown="box2ButtonDown">點此拖拽2</div> <div class="delay-box"> <span v-for="(item, index) in testData2" :key="index" :data-testdata="testFun('box2')" >{{item.value}}</span> </div> </div> </div> <script> new Vue({ el: '#app', data: { // 測試數據 testData1: [ {value: '1'}, {value: '2'}, {value: '3'}, {value: '4'}, {value: '5'}, {value: '6'}, {value: '7'}, {value: '9'}, {value: '10'} ], testData2: [ {value: '1'}, {value: '2'}, {value: '3'}, {value: '4'}, {value: '5'}, {value: '6'}, {value: '7'}, {value: '9'}, {value: '10'} ], // 1 box1X: 0, box1Y: 0, box1L: 0, box1T: 0, box1CurrentX: 0, box1CurrentY: 0, // 2 box2X: 0, box2Y: 0, box2L: 0, box2T: 0, box2CurrentX: 0, box2CurrentY: 100 }, computed: { box1Style() { return { top: this.box1CurrentY + 'px', left: this.box1CurrentX + 'px' }; }, box2Style() { return { top: '100px', left: '0px' }; } }, methods: { box1Start(e) { let dv = this.$refs.box1; this.box1X = e.clientX; this.box1Y = e.clientY; this.box1L = dv.offsetLeft; this.box1T = dv.offsetTop; }, box1Move(e) { console.log('box1 move'); let nx = e.clientX; let ny = e.clientY; let nl = nx - (this.box1X - this.box1L); let nt = ny - (this.box1Y - this.box1T); // 代碼關鍵處 this.box1CurrentX = nl; this.box1CurrentY = nt; }, box1End(e) { window.removeEventListener('mousemove', this.box1Move); window.removeEventListener('mouseup', this.box1End); }, box1ButtonDown(e) { this.box1Start(e); window.addEventListener('mousemove', this.box1Move); window.addEventListener('mouseup', this.box1End); }, box2Start(e) { // 獲取元素 let dv = this.$refs.box2; // 獲取x座標和y座標 this.box2X = e.clientX; this.box2Y = e.clientY; // 獲取左部和頂部的偏移量 this.box2L = dv.offsetLeft; this.box2T = dv.offsetTop; }, box2Move(e) { console.log('box2 move'); let nx = e.clientX; let ny = e.clientY; let nl = nx - (this.box2X - this.box2L); let nt = ny - (this.box2Y - this.box2T); // 代碼關鍵處 this.box2CurrentX = nl; this.box2CurrentY = nt; let legendBox = this.$refs.box2; legendBox.style.left = nl + 'px'; legendBox.style.top = nt + 'px'; }, box2End(e) { window.removeEventListener('mousemove', this.box2Move); window.removeEventListener('mouseup', this.box2End); }, box2ButtonDown(e) { this.box2Start(e); window.addEventListener('mousemove', this.box2Move); window.addEventListener('mouseup', this.box2End); }, testFun(name) { // 如果此時加入長時間處理代碼,就會降低mousemove幀數率 console.time(name + '-delay'); for (let i = 0; i < 10240000; i++) {} console.timeEnd(name + '-delay'); } } }) </script> <style> *::selection { background: none; } .box { position: fixed; z-index: 100; width: 200px; height: 80px; } .dargbtn { margin: 15px; color: #222222; background: #eee; cursor: pointer; } .box1 { background: #c0c; } .box2 { background: #0cc; } </style> </body> </html>