Demo - 演示地址:http://a-1.vip/demo/exercise Demo - 原生js 轮播图:http://a-1.vip/demo/slideshow // 拖拽方法 // 当鼠标被按下、 demo.onmousedown = function(coord) { // 判断为鼠标左键、 if (coord.button == 0) { var _this = this; // 当鼠标移动、 document.onmousemove = function(e) { _this.style.left = e.pageX - coord.offsetX + 'px'; _this.style.top = e.pageY - coord.offsetY + 'px'; } // 当鼠标抬起、 document.onmouseup = function() { document.onmousemove = null; document.onmouseup = null; // startMove(_this); } } } //························································································ // 匀速运动 function balanceSports(event, speed, locX, locY) { clearInterval(event.timer); locX = locX - event.offsetLeft > 0 ? locX - event.offsetWidth : locX; locY = locY - event.offsetTop > 0 ? locY - event.offsetHeight : locY; var spX = locX - event.offsetLeft > 0 ? speed : -speed; var spY = locY - event.offsetTop > 0 ? speed : -speed; event.timer = setInterval(function() { if (Math.abs(locX - event.offsetLeft) < Math.abs(spX) && Math.abs(locY - event.offsetTop) < Math.abs(spY)) { clearInterval(event.timer); } else if (Math.abs(locX - event.offsetLeft) < Math.abs(spX)) { spX = 0; event.style.left = locX + 'px'; } else if (Math.abs(locY - event.offsetTop) < Math.abs(spY)) { spY = 0; event.style.top = locY + 'px'; } else { event.style.left = event.offsetLeft + spX + 'px'; event.style.top = event.offsetTop + spY + 'px'; } }, 10); } // 缓冲运动 function bufferSports(event, speed, locX, locY) { clearInterval(event.timer); locX = locX - event.offsetLeft > 0 ? locX - event.offsetWidth : locX; locY = locY - event.offsetTop > 0 ? locY - event.offsetHeight : locY; event.timer = setInterval(function() { var spX = (locX - event.offsetLeft) / speed; spX = spX > 0 ? Math.ceil(spX) : Math.floor(spX); var spY = (locY - event.offsetTop) / speed; spY = spY > 0 ? Math.ceil(spY) : Math.floor(spY); if (locX - event.offsetLeft == 0 && locY - event.offsetTop == 0) { clearInterval(event.timer); } else { event.style.left = event.offsetLeft + spX + 'px'; event.style.top = event.offsetTop + spY + 'px'; } }, 10) } 多属性变化·运动实例:http://a-1.vip/demo/exercise/index2.html // 支持多个属性动态变化,缓冲运动 bufferMove(元素,属性对象,速度,回调函数) // bufferMove(this, {top: '150px',left: '300px',width: '600px',height: '600px',opacity: '0.05'}, 17, function() {console.log('Hello World~');}); function bufferMove(event, attrObj, speed, callback) { // 兼容写法:取style样式属性、 function getStyle(dom, attr) { if (window.getComputedStyle) { return window.getComputedStyle(dom, null)[attr]; } else { return dom.currentStyle[attr]; } } // 每次执行时结束上一次的定时器、 clearInterval(event.timer); var peed = null, // 每次运动的速度、 current = null, // 当前位置、 target = null; // 终点位置、 event.timer = setInterval(function() { var trigger = true; for (var key in attrObj) { if (key == 'opacity') { target = parseFloat(attrObj[key]) * 100; current = parseFloat(getStyle(event, key)) * 100; } else { target = parseFloat(attrObj[key]); current = parseInt(getStyle(event, key)); } peed = (target - current) / speed; peed = peed > 0 ? Math.ceil(peed) : Math.floor(peed); if (key == 'opacity') { event.style[key] = (current + peed) / 100; } else { event.style[key] = current + peed + 'px'; } if (target != current) { trigger = false; } } if (trigger) { clearInterval(event.timer); typeof(callback) === 'function' ? callback(): null; // 回调函数、 } }, 20) } // 支持多个属性动态变化,弹性运动 elasticMove(元素,属性对象,回调函数) // elasticMove(this, {top: '150px',left: '300px',width: '600px',height: '600px',opacity: '0.05'}, 17, function() {console.log('Hello World~');}); function elasticMove(event, attrObj, callback) { // 兼容写法:取style样式属性、 function getStyle(dom, attr) { if (window.getComputedStyle) { return window.getComputedStyle(dom, null)[attr]; } else { return dom.currentStyle[attr]; } } // 每次执行时结束上一次的定时器、 clearInterval(event.timer); var f = 11, // 力度、 m = 0.85; // 阻力、 var speed = []; for (var key in attrObj) { speed[key] = 0; } event.timer = setInterval(function() { var trigger = true; for (var key in attrObj) { trigger = false; if (key == 'opacity') { target = parseFloat(attrObj[key]) * 100; current = parseFloat(getStyle(event, key)) * 100; } else { target = parseFloat(attrObj[key]); current = parseInt(getStyle(event, key)); } var a = (target - current) / f; speed[key] += a; speed[key] *= m; if (key == 'opacity') { event.style[key] = (current + speed[key]) / 100; } else { event.style[key] = current + speed[key] + 'px'; } if (Math.abs(speed[key]) < 1 && Math.abs(target - current) < 1) { event.style[key] = attrObj[key]; delete attrObj[key]; break; } } if (trigger) { clearInterval(event.timer); typeof(callback) === 'function' ? callback(): null; // 回调函数、 } }, 25) } 模拟重力场·拖拽实例:http://a-1.vip/demo/exercise/index3.html // 模拟重力场,弹性运动。startMove(元素对象, speedX, speedY) function startMove(event, speedX, speedY) { var g = 3; clearInterval(event.timer); event.timer = setInterval(function() { speedY += g; var newLeft = event.offsetLeft + speedX; var newTop = event.offsetTop + speedY; var dom = document.documentElement; // console.log(dom.clientHeight - event.clientHeight - newTop, dom.clientHeight, event.offsetHeight); // 判断event元素是否到顶边、 if (newTop <= 0) { speedY *= -1; speedX *= 0.8; speedY *= 0.8; newTop = 0; } // 判断event元素是否到左边、 if (newLeft <= 0) { speedX *= -1; speedX *= 0.8; speedY *= 0.8; newLeft = 0; } // 判断event元素是否到底边、 if (newTop >= dom.clientHeight - event.clientHeight) { speedY *= -1; speedX *= 0.8; speedY *= 0.8; newTop = dom.clientHeight - event.clientHeight; } // 判断event元素是否到右边、 if (newLeft >= dom.clientWidth - event.clientWidth) { speedX *= -1; speedX *= 0.8; speedY *= 0.8; newLeft = dom.clientWidth - event.clientWidth; } // 判断是否接近于0、 speedX = Math.abs(speedX) < 1 ? 0 : speedX; speedY = Math.abs(speedY) < 1 ? 0 : speedY; // 判断是否结束、 if (speedX == 0 && speedY == 0 && newTop == dom.clientHeight - event.clientHeight) { clearInterval(event.timer); } else { event.style.left = newLeft + 'px'; event.style.top = newTop + 'px'; } }, 20); }