这是我更新和修改过的脚本,它完全有效,除了我想要普及它...观察****我怎样才能做到这一点我不必做function(e){BOX.Draggable.elemen = e.target || e.srcElement; elementDraggable(e);
每次我需要将可拖动功能用于不同的元素?
window.onload = addListeners;
var BOX = function(){
return{
Draggable: function(){}
};
}();
function addListeners(){
document.getElementById('div').addEventListener('contextmenu', menumove, false);
**document.getElementById('div').addEventListener('mousedown', function(e){BOX.Draggable.elemen = e.target || e.srcElement; elementDraggable(e);}, false);**
}
function elementDraggable(e){
var e = e || window.event;
var div = BOX.Draggable.elemen;
BOX.Draggable.innerX = e.clientX + window.pageXOffset - div.offsetLeft;
BOX.Draggable.innerY = e.clientY + window.pageYOffset - div.offsetTop;
window.addEventListener('mousemove', elementMove, false);
window.addEventListener('mouseup', function(){
window.removeEventListener('mousemove', elementMove, false);
}, true);
function elementMove(e){
div.style.position = 'absolute';
div.style.left = e.clientX + window.pageXOffset - BOX.Draggable.innerX + 'px';
div.style.top = e.clientY + window.pageYOffset - BOX.Draggable.innerY + 'px';
}
}
答案 0 :(得分:66)
jQuery是你的选择吗?由于代码已经存在,它使您正在做的事情变得非常简单。
http://jqueryui.com/demos/draggable/
<强> Demo 强>
JavaScript代码
window.onload = addListeners;
function addListeners(){
document.getElementById('dxy').addEventListener('mousedown', mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);
}
function mouseUp()
{
window.removeEventListener('mousemove', divMove, true);
}
function mouseDown(e){
window.addEventListener('mousemove', divMove, true);
}
function divMove(e){
var div = document.getElementById('dxy');
div.style.position = 'absolute';
div.style.top = e.clientY + 'px';
div.style.left = e.clientX + 'px';
}
答案 1 :(得分:51)
这是一个很好的no-jQuery脚本来拖动div:http://jsfiddle.net/g6m5t8co/1/
<!doctype html>
<html>
<head>
<style>
#container {
position:absolute;
background-color: blue;
}
#elem{
position: absolute;
background-color: green;
-webkit-user-select: none;
-moz-user-select: none;
-o-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}
</style>
<script>
var mydragg = function(){
return {
move : function(divid,xpos,ypos){
divid.style.left = xpos + 'px';
divid.style.top = ypos + 'px';
},
startMoving : function(divid,container,evt){
evt = evt || window.event;
var posX = evt.clientX,
posY = evt.clientY,
divTop = divid.style.top,
divLeft = divid.style.left,
eWi = parseInt(divid.style.width),
eHe = parseInt(divid.style.height),
cWi = parseInt(document.getElementById(container).style.width),
cHe = parseInt(document.getElementById(container).style.height);
document.getElementById(container).style.cursor='move';
divTop = divTop.replace('px','');
divLeft = divLeft.replace('px','');
var diffX = posX - divLeft,
diffY = posY - divTop;
document.onmousemove = function(evt){
evt = evt || window.event;
var posX = evt.clientX,
posY = evt.clientY,
aX = posX - diffX,
aY = posY - diffY;
if (aX < 0) aX = 0;
if (aY < 0) aY = 0;
if (aX + eWi > cWi) aX = cWi - eWi;
if (aY + eHe > cHe) aY = cHe -eHe;
mydragg.move(divid,aX,aY);
}
},
stopMoving : function(container){
var a = document.createElement('script');
document.getElementById(container).style.cursor='default';
document.onmousemove = function(){}
},
}
}();
</script>
</head>
<body>
<div id='container' style="width: 600px;height: 400px;top:50px;left:50px;">
<div id="elem" onmousedown='mydragg.startMoving(this,"container",event);' onmouseup='mydragg.stopMoving("container");' style="width: 200px;height: 100px;">
<div style='width:100%;height:100%;padding:10px'>
<select id=test>
<option value=1>first
<option value=2>second
</select>
<INPUT TYPE=text value="123">
</div>
</div>
</div>
</body>
</html>
答案 2 :(得分:13)
嗯,您的移动代码简化为:
div.style.position = "absolute";
div.style.top = e.clientY - (e.clientY - div.offsetTop) + "px";
div.style.left = e.clientX - (e.clientX - div.offsetLeft) + "px";
此处的基本数学 - e.clientX
和e.clientY
对此处的排名完全没有影响,因此您只需取offsetLeft
并将其重新分配给style.left
,顶部相同。因此没有任何动作。
您需要做的是在clientX
发生时保存clientY
和mousedown
,然后根据该值进行减法。
哦,你也在设置事件监听器错误。它现在的方式是,它运行divMove
一次,返回值(此处为undefined
)是附加为侦听器的函数。相反,请使用function(e) {divMove(dxy,e || window.event);}
。
答案 3 :(得分:5)
我稍微修改了Shaedo's代码,将其包装在一个函数中并添加了一个功能,您只能将其中的一部分或其子项拖动一个元素,比如div的标题栏。请注意,在此演示中,您只能拖动红色区域以移动蓝色区域。
function makeDragable(dragHandle, dragTarget) {
let dragObj = null; //object to be moved
let xOffset = 0; //used to prevent dragged object jumping to mouse location
let yOffset = 0;
document.querySelector(dragHandle).addEventListener("mousedown", startDrag, true);
document.querySelector(dragHandle).addEventListener("touchstart", startDrag, true);
/*sets offset parameters and starts listening for mouse-move*/
function startDrag(e) {
e.preventDefault();
e.stopPropagation();
dragObj = document.querySelector(dragTarget);
dragObj.style.position = "absolute";
let rect = dragObj.getBoundingClientRect();
if (e.type=="mousedown") {
xOffset = e.clientX - rect.left; //clientX and getBoundingClientRect() both use viewable area adjusted when scrolling aka 'viewport'
yOffset = e.clientY - rect.top;
window.addEventListener('mousemove', dragObject, true);
} else if(e.type=="touchstart") {
xOffset = e.targetTouches[0].clientX - rect.left;
yOffset = e.targetTouches[0].clientY - rect.top;
window.addEventListener('touchmove', dragObject, true);
}
}
/*Drag object*/
function dragObject(e) {
e.preventDefault();
e.stopPropagation();
if(dragObj == null) {
return; // if there is no object being dragged then do nothing
} else if(e.type=="mousemove") {
dragObj.style.left = e.clientX-xOffset +"px"; // adjust location of dragged object so doesn't jump to mouse position
dragObj.style.top = e.clientY-yOffset +"px";
} else if(e.type=="touchmove") {
dragObj.style.left = e.targetTouches[0].clientX-xOffset +"px"; // adjust location of dragged object so doesn't jump to mouse position
dragObj.style.top = e.targetTouches[0].clientY-yOffset +"px";
}
}
/*End dragging*/
document.onmouseup = function(e) {
if (dragObj) {
dragObj = null;
window.removeEventListener('mousemove', dragObject, true);
window.removeEventListener('touchmove', dragObject, true);
}
}
}
makeDragable('#handle', '#moveable')
&#13;
#moveable {
width: 100px;
height: 100px;
background: blue;
}
#handle {
width: 50px;
height: 50px;
cursor: move;
background: red;
}
&#13;
<div id="moveable">
<div id="handle">
</div>
</div>
&#13;
答案 4 :(得分:0)
“niente00”代码的另一种方法。
init : function(className){
var elements = document.getElementsByClassName(className);
for (var i = 0; i < elements.length; i++){
elements[i].onmousedown = function(){mydragg.startMoving(this,'container',event);};
elements[i].onmouseup = function(){mydragg.stopMoving('container');};
}
}
答案 5 :(得分:0)
尝试了jnoreiga可接受的答案后,我发现被拖动的元素突然突然捕捉到左上角,而不是保持相同的相对位置,这很令人讨厌。
此代码段通过偏移量防止了上述尴尬的行为,并提供了一个简单的界面来一次或通过forEach
调用或类似操作一次创建可拖动元素。
window.onload = function() {
draggable(document.getElementById('foo'));
}
function draggable(el) {
el.addEventListener('mousedown', function(e) {
var offsetX = e.clientX - parseInt(window.getComputedStyle(this).left);
var offsetY = e.clientY - parseInt(window.getComputedStyle(this).top);
function mouseMoveHandler(e) {
el.style.top = (e.clientY - offsetY) + 'px';
el.style.left = (e.clientX - offsetX) + 'px';
}
function reset() {
window.removeEventListener('mousemove', mouseMoveHandler);
window.removeEventListener('mouseup', reset);
}
window.addEventListener('mousemove', mouseMoveHandler);
window.addEventListener('mouseup', reset);
});
}
/* The only required styling is position: absolute */
#foo {
position: absolute;
border: 1px solid black;
overflow: hidden;
}
/* Prevents inconsistent highlighting of element while being dragged
Copied from https://stackoverflow.com/questions/826782 */
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
<div id="foo" class="noselect">This is a draggable div!</div>
答案 6 :(得分:0)
在clientY
事件 中使用clientX
,pageY
,pageX
或dragend
的任何解决方案在Firefox中将完全失败。 来源:Bugzilla: Bug #505521, Set screen coordinates during HTML5 drag event。
我们如何获得此限制? document
的{{1}}事件也与被拖动元素的drop
事件在同一时间触发。但是,我们可以在Firefox中看到dragend
和clientY
之类的东西。所以,让我们使用它。
两个有效的演示,100%纯JavaScript解决方案 :SO代码段和JSBin。
clientX
var startx = 0;
var starty = 0;
dragStartHandler = function(e) {
startx = e.clientX;
starty = e.clientY;
}
dragOverHandler = function(e) {
e.preventDefault();
return false;
}
dragEndHandler = function(e) {
if(!startx || !starty) {
return false;
}
var diffx = e.clientX - startx;
var diffy = e.clientY - starty;
var rect = e.target.getBoundingClientRect();
var offset = {
top: rect.top + window.scrollY,
left: rect.left + window.scrollX,
};
var newleft = offset.left + diffx;
var newtop = offset.top + diffy;
e.target.style.position = 'absolute';
e.target.style.left = newleft + 'px';
e.target.style.top = newtop + 'px';
startx = 0;
starty = 0;
}
document.getElementsByClassName("draggable")[0].addEventListener('dragstart', dragStartHandler);
document.addEventListener('dragover', dragOverHandler);
document.addEventListener('drop', dragEndHandler);
.draggable {
border: 1px solid black;
cursor: move;
width:250px;
};
说明:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<BR><BR><BR>
<div id="draggable1" class="draggable" draggable="true">
Hey, try to drag this element!
</div>
</body>
</html>
:这绑定到可拖动元素。在这里,我们要做的就是在开始时记录当前的x / y坐标。dragStartHandler()
:这绑定到文档,因此我们可以覆盖默认的拖拽行为。进行任何类型的拖放都是必需的。dragOverHandler()
:这绑定到dragEndHandler()
的{{1}}。通常,我们希望将其绑定到document
的{{1}},但是由于缺少drop
和element
,因此将其绑定到文档。这恰好满足了在调用dragend时想要发生的事情,除了您有x / y坐标。使用的公式是:
dragend
这很复杂,但是要计算和应用样式,仅针对x维度,代码就是...
clientY