复制就可以用啦 <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>