ps:代码是其他提供,其中所有文字都是个人理解,如果有什么错误和想法欢迎沟通~希望对你有帮助,biu
<h1>拖动 /拖曳效果</h1>
首先把需要拖动的部分放到一个div里面,然后导入相关的.js文件
<code>
<div class="login_logo_webqq"></div>
</code>
由于IE10以上不支持document.getElementsClassName(),所以为了解决所有浏览器兼容的问题,需要把获取ClassName封装起来.
通过Class获取元素需要两个参数,一个时ClassName类名,一个是父元素,第二个参数也不是必须的,如果不写就打上document,就会寻找所有class的元素,写了就寻找这个父元素下的ClassName.
function getByClass(clsName,parent){
var oParent=parent?document.getElementById(parent):document,
eles=[],
解释:如果传入parent就获取他的id然后付给变量,没有传的话就放入document
由于类名可能不唯一,所以得到的是一个数组,就把他放到这个eles数组里面.
elements=oParent.getElementsByTagName('*');
```
现在获取到父元素下面所有的元素,然后进行遍历
for(var i=0,l=elements.length;i<l;i++){
if(elements[i].className==clsName){
eles.push(elements[i]);
}
}
return eles;
}
现在我们得到了这块元素之后,我们调用一个drag的函数,来完成拖拽.
<h2>拖动一共要经历三步
1>在标题区域按下开始拖动
2>在页面中拖动
3>释放鼠标的时候停止拖动
</h2>
window.onload=drag;
function drag(){
var oTitle=getByClass('login_logo_webqq','loginPanel')[0];
拖曳,获取了这个div,
oTitle.onmousedown=fnDown;
```
onmousedown:在用户按下任意鼠标按钮时出发事件fndown,为了方便阅读我将fnDown函数放到下面.<h3>拖动的原理其实就是拖动的部分和你的光标的坐标是一样的.</h3>
光标的位置可以通过clientX 和 clientY来得到.
鼠标事件都是在浏览器的特定位置上发生的,这个位置的信息保存在事件的clientX和clientY属性中.所有浏览器都支持这两个属性,他们的值表示事件发生时鼠标指针在视口中的水平和垂直坐标,不包括页面滚动的距离,也就是说可以通过这两个属性获得光标的xy坐标,然后让弹框也是这个坐标不就实现了拖动
function fnDown(event){
event = event || window.event;
var oDrag=document.getElementById('loginPanel'),
// 光标按下时光标和面板之间的距离
disX=event.clientX-oDrag.offsetLeft,
disY=event.clientY-oDrag.offsetTop;
//用来获取弹框左上角相对浏览器距离,下面会解释
document.onmousemove=function(event){
event = event || window.event;
//IE得用window.event,得到事件对象
fnMove(event,disX,disY);
function fnMove(e,posX,posY){
var oDrag=document.getElementById('loginPanel'),//改变他得先把他取出来
```
<p>
<h5>错误演示:</h5>
按理来说只要改变他的位置定位就可以了
oDrag.style.left = event.clientX+'px';
oDrang.style.top = event.clientY+'px';
<p>
这样操作会明显发现,当你光标在拖动区域按下鼠标时,光标会跑到弹框的左上角,这样的话用户体验就不太好了.
bug分析:
由于你告诉浏览器光标在哪,弹框在那,得有个标准吧,所以就是时你的弹框左上角和光标位置一样.而且你本身定义的top和left就是左上角的位置.
<h5>解决方案:</h5>
所以就是说我们不能直接告诉他让和光标一个位置,而是在你光标按下的位置上的基础来改变位置.所以就是要获取到按下鼠标的位置和左上角的位置有什么关系,在这个基础上改变位置.
![guangbaio.png](http://upload-images.jianshu.io/upload_images/3189429-199a5ec9533f500c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
其中黄色的时光标,蓝色时标题框,其中的白线就是我们要获取的坐标.而白线的距离就是光标相对浏览器的距离减去弹框跟窗口之间的距离
![weizhi.png](http://upload-images.jianshu.io/upload_images/3189429-c6bb703bdb99f946.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
</p>
</p>
l=e.clientX-posX,
t=e.clientY-posY,
l,t现在是获得的白线的距离
注意任何拖动的拖动的东西,都需要一个绝对定位,在css中.
<p>
<h5>错误发现:</h5>
那现在又会发现,弹框可以任意拖动,也就是可以一直把滚动条撑起来,这样的话用户体验也不好
<h5>分析解决:</h5>
我们现在就需要,当弹框接触浏览器边界的时候不能在想外拖动了.所以就用限制一个范围,不能随意拉动了.对于左边也就时lt变成负数的时候让他强制变成0.对于右边就拖动的最大范围就是页面宽减去弹框宽度,当坐标大于这个范围的时候就强制变成最大坐标
</p>
winW=document.documentElement.clientWidth || document.body.clientWidth,
winH=document.documentElement.clientHeight || document.body.clientHeight,
maxW=winW-oDrag.offsetWidth-10,
//这里减10是因为关闭按钮允许溢出十个像素
maxH=winH-oDrag.offsetHeight;
if(l<0){
l=0;
}else if(l>maxW){
l=maxW;
}
if(t<0){
t=10;
//这样才能底对齐
}else if(t>maxH){
t=maxH;
}
oDrag.style.left=l+'px';
oDrag.style.top=t+'px';
}
}
onmousemove当鼠标指针在元素内部移动时重复地触发,也就是每移动一下都会触发这个事件.
// mouseup当用户释放鼠标触发事件
document.onmouseup=function(){
document.onmousemove=null;
//就是移动的时候什么也不做,释放事件
document.onmouseup=null;
}
}
<h4>总结</h4>
总的来说就是获取到可以点击鼠标拖动的区域,然后再处理好弹框和鼠标坐标的关系.放开鼠标的时候释放事件.最后再处理一下边界的问题就好了.我个人认为这个这个坐标的问题还是很值得分析的.