Простой Drag & Drop
Сегодня на работе делать было нефиг, решил написать простенький скрипт D&D.
Вышло вроде неплохо. Тестировал под IE7, IE6, Chrome 1.0.154.48, Opera 964, FireFox 307. Фишка еще что под всеми броузерами нормально таскает <img> и учитывает скрол. Сделал его легко разбираемым и без наворотов. мб для кого нибудь окажется полезным, мб кто-то поправит или исправит меня =)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<html>
<head>
<script type="text/javascript" language="javascript">
/************COMON**************/
function getEvent(e)
{if (document.all)return event;else return e;}
function getObjFromEvent(e)
{if (document.all)return e.srcElement;else return e.target;}
/*******************************/
var dragEl = false;
var dragElParent = false;
var clickX = false;
var clickY = false;
function start()
{
simpleDrag(document.getElementById("drag1"));
simpleDrag(document.getElementById("drag2"));
dragInParent(document.getElementById("drag3"));
}
function simpleDrag(o)
{o.onmousedown = simple;}
function dragInParent(o)
{o.onmousedown = inParent;}
function dSimpleDrag(o)
{o.onmousedown = null;}
function inParent(e)
{
dragElParent = getObjFromEvent(getEvent(e)).parentNode;
startDrag(e);
}
function simple(e)
{
startDrag(e);
}
function drag(e)
{
var eObj = getEvent(e);
var newX = eObj.clientX - clickX;
var newY = eObj.clientY - clickY;
if(dragElParent)
{
if( 0 <= newX && dragElParent.offsetWidth >= ( newX + dragEl.offsetWidth ) )
dragEl.style.left = newX + "px";
else if(0 > newX)
dragEl.style.left = 0;
else if(dragElParent.offsetWidth - parseInt(dragElParent.style.left) < newX + dragEl.offsetWidth)
dragEl.style.left = dragElParent.offsetWidth - dragEl.offsetWidth + "px";
if( 0 <= newY && dragElParent.offsetHeight >= ( newY + dragEl.offsetHeight ) )
dragEl.style.top = newY + "px";
else if(0 > newY)
dragEl.style.top = 0;
else if(dragElParent.offsetHeight - parseInt(dragElParent.style.top) < newY + dragEl.offsetHeight)
dragEl.style.top = dragElParent.offsetHeight - dragEl.offsetHeight + "px";
// dragEl.innerHTML = newX +":"+ newY + "<br/>" + dragEl.style.left + ":" + dragEl.style.top;
}
else
{
dragEl.style.left = newX + "px";
dragEl.style.top = newY + "px";
}
}
function startDrag(e)
{
document.onmouseup = stopDrag;
var eObj = getEvent(e);
dragEl = getObjFromEvent(eObj);
dragEl.style.MozUserSelect = "none";
dragEl.ondragstart = dragEl.onselectstart = function(){return false;}
clickX = eObj.clientX - parseInt(dragEl.style.left) - document.body.scrollLeft;
clickY = eObj.clientY - parseInt(dragEl.style.top) - document.body.scrollTop;
document.onmousemove = drag;
if (e && dragEl.tagName.match(/img/gi))
e.preventDefault();
else if(dragEl.tagName.match(/img/gi))
eObj.returnValue= false;
return false;
}
function stopDrag()
{
document.onmousemove = null;
document.onmouseup = null;
if(dragEl)
{
dragEl.ondragstart = dragEl.onselectstart = null;
dragEl.style.MozUserSelect = "all";
dragEl = false;
dragElParent = false;
clickX = false;
clickY = false;
}
}
</script>
</head>
<body onload="start();" style="padding:0;margin:0;">
<div style="width:500px; height:600px; background-color: green; position:absolute; top:60px; left:100px;">
<div id="drag3" style="width:100px; height:100px; background-color:red; position: absolute; top:50px; left:100px;">Вытащи меня за зеленое поле :P</div>
</div>
<div id="drag1" style="width:100px; height:100px; background-color:red; position: relative; top:50px; left:1000px;">Попробуй перетащить меня или лого яндекса. ;)</div>
<img id="drag2" src="http://ya.ru/logo.png" style="position: absolute; top:200px; left:900px;"/>
</body>
</html>
Подключаем скрипт файлом. Чтобы сделать какой либо объект подвижным используем функцию simpleDrag(obj); илиdragInParent(obj);(позициониров ние объекта заведомо должно быть relative или absolute) |
Что-то больно много кода для такой маленькой функции... Мне как-то тожн нечего было делать и я написал вот что:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
body, html{
margin:0;
padding:0;
overflow:hidden;
width:100%;
height:100%;
}
div{
background-color:#CCC;
margin:10px;
border:#F00 1px solid;
}
#wBody{
position:absolute;
top:50px;
left:50px;
width:250px;
height:250px;
margin:0;
}
</style>
<script etype="text/javascript">
function xGetElementById(e){
if(!xStr(e)) return e;
if(document.getElementById) return document.getElementById(e);
else if(document.all) return document.all[e];
}
function xDef() {
for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])=='undefined') return false;}
return true;
}
function xStr() {
for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='string') return false;}
return true;
}
function xNum() {
for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='number') return false;}
return true;
}
function getCS(e,s1,s2){
if(xDef(e.currentStyle)) var s=parseInt(eval('e.currentStyle.'+s1));
else if(xDef(window.getComputedStyle)) var s=parseInt(window.getComputedStyle(e,'').getPropertyValue(s2));
return (isNaN(s))?0:s;
}
function getBorderWidth(e,width){
if(width)return getCS(e,'borderTopWidth','border-top-width')+getCS(e,'borderBottomWidth','border-bottom-width');
else return getCS(e,'borderLeftWidth','border-left-width')+getCS(e,'borderRightWidth','border-right-width')
}
function xTop(e,y){
if(xDef(y)) e.style.top=y+'px';
else return e.offsetTop-getCS(e,'marginTop','margin-top');
}
function xLeft(e,x){
if(xDef(x)) e.style.left=x+'px';
else return e.offsetLeft-getCS(e,'marginLeft','margin-left');
}
function xWidth(e,w){
if(w){if(w>0) e.style.width=w+'px'; else return 0}
else if(xNum(e.style.width)) return parseInt(e.style.width);
else return e.clientWidth+getBorderWidth(e,true);
}
function xHeight(e,h){
if(h){if(h>0) e.style.height=h+'px'; else return 0}
else if(xNum(e.style.height)) return parseInt(e.style.height);
else return e.clientHeight+getBorderWidth(e);
}
</script>
</head>
<body>
<div id="wBody">
Parent
<div id="wDrag">wDrag</div>
<div id="wReSizeXY">wReSizeXY</div>
<div id="wReSizeX">wReSizeX</div>
<div id="wReSizeY">wReSizeY</div>
<div id="wClose">wClose</div>
</div>
<script etype="text/javascript">
var wBody=xGetElementById('wBody');
var wDrag=xGetElementById('wDrag');
var wReSizeXY=xGetElementById('wReSizeXY');
var wReSizeX=xGetElementById('wReSizeX');
var wReSizeY=xGetElementById('wReSizeY');
var wClose=xGetElementById('wClose');
initWindow(wBody,wDrag,false,true,true);
initWindow(wBody,wReSizeXY,true,true,true);
initWindow(wBody,wReSizeX,true,true,false);
initWindow(wBody,wReSizeY,true,false,true);
wClose.onclick=function(){
document.body.removeChild(wBody);
}
function initWindow(oBody,oInitEvent,eType,useX,useY){
oInitEvent.onmousedown=function(event){
event=event||window.event;
var fncX=(eType)?xWidth:xLeft;
var fncY=(eType)?xHeight:xTop;
var x=event.clientX-fncX(oBody);
var y=event.clientY-fncY(oBody);
var minW=200;
var minH=200;
var cW=document.documentElement.clientWidth;
var cH=document.documentElement.clientHeight;
document.onmousemove=function(event){
event=event||window.event;
if(useX){
fncX(oBody,event.clientX-x);
if(eType){
if((xWidth(oBody)>minW)?false:xLeft(oBody)+minW>event.clientX)xWidth(oBody,minW);
if(xWidth(oBody)+xLeft(oBody)>cW)xWidth(oBody,cW-xLeft(oBody)-getBorderWidth(oBody,true));
}else{
if(xLeft(oBody)+xWidth(oBody)>cW)xLeft(oBody,cW-xWidth(oBody));
if(xLeft(oBody)<0)xLeft(oBody,0);
}
}
if(useY){
fncY(oBody,event.clientY-y);
if(eType){
if((xHeight(oBody)>minH)?false:xTop(oBody)+minH>event.clientY)xHeight(oBody,minH);
if(xHeight(oBody)+xTop(oBody)+getBorderWidth(oBody)>cH)xHeight(oBody,cH-xTop(oBody)-getBorderWidth(oBody));
}else{
if(xTop(oBody)+xHeight(oBody)>cH)xTop(oBody,cH-xHeight(oBody));
if(xTop(oBody)<0)xTop(oBody,0);
}
}
}
document.onmouseup=function(){
if(!eType){
oBody.style.top=xTop(oBody)*100/cH+'%';
oBody.style.left=xLeft(oBody)*100/cW+'%';
}
document.onmousemove=function(){return false;}
}
}
}
</script>
</body>
</html>
Помимо перетаскивания, умеет ресайзить X, Y и X+Y и закрывацца... По сути - окно... Полностью кроссбраюзерно и быстро... Для того, чтобы назначить объект для таскания используем функцию initWindow(oBody,oInitEvent,eType,useX,useY) Параметры: oBody - узел, подвергающийся тасканию/ресайзу oInitEvent - узел, который инициализирует событие eType - тип события. Булево значение: true - ресайз, false - драг. useX,useY - использовать координаты X и/или Y соответственно. Например, можно таскать/ресайзить только по X. |
давайте еще тогда статью сюда добавим - http://javascript.ru/ui/draganddrop
|
| Часовой пояс GMT +3, время: 22:53. |