做了一个弹窗,实现基本的拖拽,碰撞,自由落体等功能。
1、拖拽
三大事件:
onmousedown
onmousemove
onmouseup
思路:
a、鼠标按下,记录当前坐标(clientX,clientY);
b、在down的事件内写onmousemove事件,移动时将鼠标此时的坐标减下最初down的时候记录的坐标,将这两个值付给拖拽体做left和top。
c、在鼠标down的事件内写onmouseup事件,将omousemove和onmouseup事件清空。
window.onload = function() {
var oDiv = document.getElementById('div1');
var disX = 0;
var disY = 0;
oDiv.onmousedown = function(ev) { var ev = ev || window.event;
disX = ev.clientX - oDiv.offsetLeft;
disY = ev.clientY - oDiv.offsetTop;
document.onmousemove = function(ev) { var ev = ev || window.event;
oDiv.style.left = ev.clientX - disX + 'px';
oDiv.style.top = ev.clientY - disY + 'px'; } document.onmouseup = function() { document.onmousemove = null;
document.onmouseup = null; } }
//拖拽速度快的时候,跟不上,因为onmousemove有反应时间,将odiv的move和up事件改成document即可
}
问题
- 拖拽照片时会有浏览器的默认行为,执行return false即可。
- ie8之前的版本,选中元素就有bug,可以在选中元素上设置一个透明隔层。
setCapture():全局捕获(就是生成了一个透明的层)
releaseCapture();释放全局捕获(删除了这个层)
2、拖拽改变元素宽高
思路:
按下鼠标记录坐标,移动的过程记录当前坐标,相减即为增加的或者减少的宽高,再加上原来的拖拽体的宽即可。
window.onload = function() {
var oDiv1 = document.getElementById('div1');
var oDiv2 = document.getElementById('div2');
var disX = 0;
var disY = 0;
var disW = 0;
var disH = 0;
oDiv2.onmousedown = function(ev) {
var ev = ev || window.event;
disX = ev.clientX;
disY = ev.clientY;
disW = oDiv1.offsetWidth;
disH = oDiv1.offsetHeight;
document.onmousemove = function(ev) {
var ev = ev || window.event;
var W = ev.clientX - disX + disW;
var H = ev.clientY - disY + disH;
if (W < 100) {
W = 100;
}
if (H < 100) {
H = 100;
}
oDiv1.style.width = W + 'px';
oDiv1.style.height = H + 'px';
}
document.onmouseup = function() {
document.onmousemove = null;
document.onmouseup = null;
}
}
}
3、碰撞
让弹窗在屏幕内进行碰撞,碰到上下左右的时候返回继续碰撞。
思路:判断left和top值是否到达临界条件,到达后将速度变为相反数即可。
window.onload = function() {
var oDiv = document.getElementById('div1');
startMove();
var iSpeedX = 10;
var iSpeedY = 10;
function startMove() {
setInterval(function() {
var L = oDiv.offsetLeft + iSpeedX;
var T = oDiv.offsetTop + iSpeedY;
if (T > document.documentElement.clientHeight - oDiv.offsetHeight) {
T = document.documentElement.clientHeight - oDiv.offsetHeight;
iSpeedY *= -1;
} else if (T < 0) {
T = 0;
iSpeedY *= -1;
}
if (L > document.documentElement.clientWidth - oDiv.offsetWidth) {
L = document.documentElement.clientWidth - oDiv.offsetWidth;
iSpeedX *= -1;
} else if (L < 0) {
L = 0;
iSpeedX *= -1;
}
oDiv.style.top = T + 'px';
oDiv.style.left = L + 'px';
}, 30);
}
}
4、自由落体
思路,设置一个定时器,每次走过定时器的时候速度加3,这样起到加速运动的作用,最后小球落到最底下的时候弹起,并慢慢的停止运动,达到临界状态时将速度变为相反数并乘一个小于1的数(相当于摩擦力),每碰撞一次都有速度的损耗。
window.onload=function(){
var oInput=document.getElementById('input1');
var oDiv=document.getElementById('div1');
var timer=null;
var iSpeed=0;
oInput.onclick=function(){
startMove()
}
function startMove(){
clearInterval(timer);
timer=setInterval(function(){
iSpeed+=3;
var T=oDiv.offsetTop+iSpeed;
if(T>document.documentElement.clientHeight-oDiv.offsetHeight){
T=document.documentElement.clientHeight-oDiv.offsetHeight;
iSpeed*=-1;
iSpeed*=0.75;
}
oDiv.style.top=T+'px';
},30)
}
}
5、拖出去的弹窗
效果:将弹窗快速拖出去,就快速的运动,慢速的拖出去就慢速的运动,怎么达到这个效果呢,通过onmousemove事件的延迟,记录拖出去的最后两次坐标。移动慢的话间隔就小,速度就有,这样就可以让速度和拖拽保持一致。
document.onmousemove = function(ev) {
var ev = ev || window.event;
oImg.style.left = ev.clientX - disX + 'px';
oImg.style.top = ev.clientY - disY + 'px';
iSpeedX = ev.clientX - prevX;
iSpeedY = ev.clientY - prevY; //最后一个点
prevX = ev.clientX;
prevY = ev.clientY; //倒数第二个点
}
6、中间打开
效果:刚加载的时候从中间散开
思路:先将宽高设为0,然后在设置定时器将宽高加起来,也同时设置left和top值
function toChange(iTarget) {
var offsetL = oImg.offsetLeft;
var offsetT = oImg.offsetTop;
var timer = setInterval(function() {
if (oImg.offsetWidth == iTarget) {
clearInterval(timer);
startMove();
} else {
oImg.style.width = oImg.offsetWidth + 10 + 'px';
oImg.style.height = oImg.offsetHeight + 10 + 'px';
oImg.style.left = offsetL - oImg.offsetWidth / 2 + 'px';
oImg.style.top = offsetT - oImg.offsetHeight / 2 + 'px';
}
}, 30)
}