js高阶之-元素在限制范围内的拖动
一.补充知识
元素的offsetLeft
offsetTop
offsetLeft 和 offsetTop 属性返回当前元素的偏移位置。IE 怪异模式以父元素为参照进行偏移位置,DOM 标准模式以最近定位元素为参照进行偏移的位置,offsetLeft是离其最近的已经定位的元素,如果没有就相对于body元素计算
对应最近父元素情况
1.body元素
2.table,th,tr,th元素,但其应具有position:releative\absolute,fixed
3.除position:static的定位元素
二.元素的拖动---任意位置
拖放的三个事情
鼠标落下,锁定了鼠标与元素的相对位置
disX=event.pageX-oDiv.offsetLeft;
disY=event.pageY-oDiv.offsetTop;
鼠标移动时,鼠标改变,元素同时改变位置(反推过程)
oDiv.style.left=event.pageX-disX+
oDiv.style.top=event.pageY-disY+
鼠标抬起,解除上面的效果
document.οnmοusemοve=document.οnmοuseup=null;//取消移动效果
实现源码:
var oDiv=document.querySelector("div");
oDiv.onmousedown=function(){
//鼠标距离元素的位置
var disX=event.pageX-oDiv.offsetLeft;//元素距离页面
var disY=event.pageY-oDiv.offsetTop;
document.onmousemove=function(){//换成document---防止位置拖放扔掉现象
//反推
oDiv.style.left=event.pageX-disX+"px";
oDiv.style.top=event.pageY-disY+"px";
}
document.onmouseup=function(){
document.onmousemove=document.onmouseup=null;//取消移动效果
}
stopDefault(event);
}
//阻止浏览器默认行为函数封装
function stopDefault( e ) { //封装函数,该处的event应该为外面传进来的---阻止浏览器默认行为
if ( e && e.preventDefault ){ //如果存在preventDefault,则这是一个非IE浏览器
e.preventDefault(); //阻止默认浏览器动作(W3C)
}else {
window.event.returnValue = false; //IE中阻止函数器默认动作的方式
}
}
三.元素在限制范围内的拖拽
1.布局效果
<div class="parent">
<div class="child"></div>
</div>
2.CSS样式设置
<style>
.parent{
width: 500px;
height: 300px;
position: relative;
background-color: red;
margin: 0 auto;
}
.child{
position: absolute;
left: 0;
top: 0;
width: 150px;
height: 150px;
background-color: yellow;
}
</style>
3.1锁定子元素相对父元素的位置
myjs.js库里的函数offsetWindow(obj)---获取元素相对页面的位置
var ochoff= offsetWindow(this);---子元素
var disX=event.pageX-ochoff[0];
var disY=event.pageY-ochoff[1];
获取子元素到父元素的相对位置(将来要到达的位置)
var oPaoff= offsetWindow(oPar);
var willLeft=event.pageX-disX-oPaoff[0];
var willTop=event.pageY-disY-oPaoff[1];
3.2锁定边界位置
将来要到达的左上位置要大于0且小于右,下边界
willLeft=Math.max(willLeft,0);
willTop=Math.max(willTop,0);
右下
父元素宽度-子元素宽度=所能拖动的最大距离
willLeft=Math.min(oPar.offsetWidth-oCh.offsetWidth,willLeft);
willTop=Math.min(oPar.offsetHeight-oCh.offsetHeight,willTop);
4.源码
<script>
var oPar=document.querySelector(".parent");
var oCh=document.querySelector(".child");
oCh.onmousedown=function(){
// 鼠标相对元素的位置
var ochoff= offsetWindow(this);
var disX=event.pageX-ochoff[0];
var disY=event.pageY-ochoff[1];
document.onmousemove=function(){
var oPaoff= offsetWindow(oPar);
//子元素相对父元素的位置
var willLeft=event.pageX-disX-oPaoff[0];
var willTop=event.pageY-disY-oPaoff[1];
//锁定边界
willLeft=Math.max(willLeft,0);
willTop=Math.max(willTop,0);
willLeft=Math.min(oPar.offsetWidth-oCh.offsetWidth,willLeft);
willTop=Math.min(oPar.offsetHeight-oCh.offsetHeight,willTop);
oCh.style.left=willLeft+"px";
oCh.style.top=willTop+"px";
}
document.onmouseup=function(){
document.onmousemove=document.onmouseup=null;//取消移动效果
}
stopDefault(event);//文字内容或产生 新页面
}
</script>
四.元素拖动练习1
*大图拖放永远不出现留白
唯一不同点:边界大小互换
willLeft=Math.min(willLeft,0);
willTop=Math.min(willTop,0);
willLeft=Math.max(oDiv.offsetWidth-oImg.offsetWidth,willLeft);
willTop=Math.max(oDiv.offsetHeight-oImg.offsetHeight,willTop);
源码:
<style>
div{
width: 1080px;
height: 535px;
background-color: red;
border: 1px black solid;
margin: 50px auto;
overflow: hidden;
position: relative;
}
img{
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div>
<img src="移动图片.jpg" alt="">
</div>
</body>
<script src="myJs.js"></script>
<script>
var oDiv=document.querySelector("div");
var oImg=document.querySelector("img");
oImg.onmousedown=function(){
var Ioff= offsetWindow(this);
var disX=event.pageX-Ioff[0];
var disY=event.pageY-Ioff[1];
document.onmousemove=function(){
var Doff= offsetWindow(oDiv);
//边界设置
var willLeft=event.pageX-disX-Doff[0];
var willTop=event.pageY-disY-Doff[1];
//大小互换卡边界
willLeft=Math.min(willLeft,0);
willTop=Math.min(willTop,0);
willLeft=Math.max(oDiv.offsetWidth-oImg.offsetWidth,willLeft);
willTop=Math.max(oDiv.offsetHeight-oImg.offsetHeight,willTop);
oImg.style.left=willLeft+"px";
oImg.style.top=willTop+"px";
}
// 取消默认情况
document.onmouseup=function(){
document.onmousemove=document.onmouseup=null;//取消移动效果
}
stopDefault(event);//文字内容或产生 新页面
}
</script>
五.元素的拖动练习2
*自制滚动条效果
1.布局
<body>
<div class="wrap">
<div class="line"></div>
</div>
<div class="box"></div>
</body>
2.CSS样式
.wrap{
width: 20px;
height: 400px;
background-color: #cccccc;
position: absolute;
left: 200px;
top: 200px;
}
.line{
width: 20px;
height: 50px;
background-color: blue;
position: absolute;
left: 0px;
top: 0px;
}
3.JS源码
var oLoff=offsetWindow(this);
var disY=event.pageY-oLoff[1];
document.onmousemove=function(){
var oWoff=offsetWindow(oW);
var willTop=event.pageY-disY-oWoff[1];
// 限制
willTop=Math.max(willTop,0);
willTop=Math.min(oW.offsetHeight-oL.offsetHeight,willTop);
oL.style.top=willTop+"px";
}
//取消设置
document.onmouseup=function(){
document.onmousemove=document.onmouseup=null;
}
stopDefault(event);
}
六.检测碰撞
补充知识: getBoundingClientRect()一个对象的大小和相对页面的位置
源码:
<title>Document</title>
<style>
.mubiao{
width: 200px;
height: 200px;
background-color: blue;
margin: 0 auto;
}
.tuofang{
width: 150px;
height: 150px;
position: absolute;
left: 0;
top: 0;
background-color: red;
}
</style>
</head>
<body>
<div class="tuofang"></div>
<div class="mubiao"></div>
</body>
<script src="myJs.js"></script>
<script>
var rectObject=document.getElementsByTagName("div")[0].getBoundingClientRect();
var oTF=document.querySelector(".tuofang");
var oMB=document.querySelector(".mubiao");
oTF.onmousedown=function(){
//获取鼠标相对元素相对位置
var disX=event.pageX-oTF.offsetLeft;
var disY=event.pageY-oTF.offsetTop;
document.onmousemove=function(){
var Wl=event.pageX-disX;
var wt=event.pageY-disY;
var oTFrect=oTF.getBoundingClientRect();
var oMBrect=oMB.getBoundingClientRect();
//判断八块位置
if(oMBrect.left>=oTFrect.right||oMBrect.top>=oTFrect.bottom||oTFrect.left>=oMBrect.right||oMBrect.bottom<=oTFrect.top){
console.log("未撞上");
oMB.style.backgroundColor="blue";
}else{
console.log("撞上了");
oMB.style.backgroundColor="yellow";
}
oTF.style.left=Wl+"px";
oTF.style.top=wt+"px";
}
//清除原设置效果
document.onmouseup=function()
{
document.onmousemove=document.onmouseup=null;
}
stopDefault(event);
}
</script>
元素拖放所有复习问题,图文均为自己制作,不允许转载@毛毛同学