I am using the following function to drag a div by a handle:
function enableDragging(ele) {
var dragging = dragging || false,
x, y, Ox, Oy,
current;
enableDragging.z = enableDragging.z || 1;
var grabber = document.getElementById("myHandelDiv");
grabber.onmousedown = function(ev) {
current = ev.target.parentNode;
dragging = true;
x = ev.clientX;
y = ev.clientY;
Ox = current.offsetLeft;
Oy = current.offsetTop;
current.style.zIndex = ++enableDragging.z;
console.log(dragging);
window.onmousemove = function(ev) {
pauseEvent(ev);
if (dragging == true) {
var Sx = ev.clientX - x + Ox,
Sy = ev.clientY - y + Oy;
current.style.top = Sy + "px";
current.style.left = Sx + "px";
document.body.focus();
// prevent text selection in IE
document.onselectstart = function () { return false; };
// prevent IE from trying to drag an image
ev.ondragstart = function() { return false; };
return false;
}
};
window.onmouseup = function(ev) {
dragging && (dragging = false);
}
};
}
function pauseEvent(e){
if(e.stopPropagation) e.stopPropagation();
if(e.preventDefault) e.preventDefault();
e.cancelBubble=true;
e.returnValue=false;
return false;
}
I have two problems:
Does not work in IE 7 & 8, for some reason i get no errors whatsoever.
Text is selected on some browsers while dragging causing the drag to appear laggy
I initiate the drag like this:
var ele = document.getElementById("divDragWrapper");
enableDragging(ele);
Update, am now getting this error in IE:
SCRIPT5007: Unable to get value of the property 'target': object is
null or undefined
On this line: current = ev.target.parentNode;
You need to add ev = ev || window.event to all eventhander functions. Older IEs don't pass the event object within arguments. Also target is rather srcElement in those browsers.
For example:
grabber.onmousedown = function(ev) {
ev = ev || window.event;
var target = ev.target || ev.srcElement;
current = target.parentNode;
...
}
Another thing is, that older IEs can't attach onmousemove to the window. You can use document or document.body instead.
See the code in action at jsFiddle.
Related
i need a little help. i want to make something that you put in console and it press Enter bottom for 2000 times and auto click for 2000 times with no delay ! and a key for stop this action. anyone can help me ? thanks a lot !
With jQuery:
function enter_key(ctrl, alt, shift, which) {
var e = $.Event("keydown");
e.ctrlKey = false;
e.altKey = false;
e.shiftKey = false;
e.which = e.keyCode = 13;
$(document.documentElement || window).trigger(e);
}
var stop = false;
for (var i=0; i<2000; ++i) {
if (!stop) {
enter_key();
}
}
click is simpler:
var stop = false;
for (var i=0; i<2000; ++i) {
if (!stop) {
$('button').click();
}
}
and you can stop the iteration by setting:
stop = true;
i thing about this and i found a code that click on the specific position :
var elem = document.elementFromPoint(x, y);
elem.addEventListener('click', function() {
console.log('clicked')
}, false);
var support = true;
try {
if (new MouseEvent('click', {bubbles: false}).bubbles !== false) {
support = false;
} else if (new MouseEvent('click', {bubbles: true}).bubbles !== true) {
support = false;
}
} catch (e) {
support = false;
}
setInterval(function() {
if (support) {
var event = new MouseEvent('click');
}else{
var event = document.createEvent('Event');
event.initEvent('click', true, true);
}
elem.dispatchEvent(event);
},1000);
and i found this code for get mouse position :
function FindPosition(e) {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
// posx and posy contain the mouse position relative to the document
// Do something with this information
}
so how can i use this code to import mouse position in auto click code ???
I am trying to change the length of two bars (div) by mouse dragging (extending one example in eloquetjavascript book chapter 14, which involves changing the length of one bar by dragging the mouse.) The intended behavior is clicking on any bar, moving the mouse when holding the left mouse key would change the length of that bar.
Here is my implementation (also available on JSfiddle)
<script>
var lastX; // Tracks the last observed mouse X position
var rect1 = document.getElementById("bar1");
var rect2 = document.getElementById("bar2");
rect1.addEventListener("mousedown", function(){watchmousedown(rect1)});
rect2.addEventListener("mousedown", function(){watchmousedown(rect2)});
function watchmousedown(rec) {
if (event.which == 1) {
lastX = event.pageX;
addEventListener("mousemove",function(){moved(rec)});
event.preventDefault(); // Prevent selection
} else {
removeEventListener("mousedown", watchmousedown)}
}
function moved(rec) {
if (event.which != 1) {
removeEventListener("mousemove", moved);
} else {
var dist = event.pageX - lastX;
var newWidth = Math.max(10, rec.offsetWidth + dist);
rec.style.width = newWidth + "px";
lastX = event.pageX;
}
}
</script>
The problem is I can only change the length of the bar where the first mouse click event happened. I assume I didn't handle the mousedown event correctly (probably need a reset some how).
I am new to javascript, help on programming style is also appreciated.
Thanks!
Add rec. to addEventListener("mousemove", function () { so that the event listener is bound to the rec you clicked on instead of to the window.
function watchmousedown(rec) {
if (event.which == 1) {
lastX = event.pageX;
rec.addEventListener("mousemove", function () {
moved(rec)
});
event.preventDefault(); // Prevent selection
} else {
rec.removeEventListener("mousedown", watchmousedown)
}
}
Edit: I there are some event handlers not being cleaned up properly. I don't know if this would be my final code, but this is closer to how I would do it:
var lastX; // Tracks the last observed mouse X position
var rect1 = document.getElementById("bar1");
var rect2 = document.getElementById("bar2");
var moveRect1 = function () {
console.log(arguments);
moved(rect1)
};
var moveRect2 = function() {
console.log(arguments);
moved(rect2);
}
var watchRect1 = function () {
console.log(arguments);
watchmousedown(moveRect1)
};
var watchRect2 = function () {
console.log(arguments);
watchmousedown(moveRect2)
};
rect1.addEventListener("mousedown", watchRect1);
rect2.addEventListener("mousedown", watchRect2);
window.addEventListener("mouseup", function() {
removeEventListener("mousemove", moveRect1);
removeEventListener("mousemove", moveRect2);
});
function watchmousedown(moverec) {
if (event.which == 1) {
lastX = event.pageX;
addEventListener("mousemove", moverec);
event.preventDefault(); // Prevent selection
}
}
function moved(rec) {
if (event.which == 1) {
var dist = event.pageX - lastX;
var newWidth = Math.max(10, rec.offsetWidth + dist);
rec.style.width = newWidth + "px";
lastX = event.pageX;
}
}
Edit: removed a line that didn't do anything
The app works wonderfully on desktop, but not on mobile. When you click DONE, the app will open a new window and show you the output of the drawings, but on iOS, all the coordinates are 0,0... so it looks like the points simply are not being saved in mobile devices.
The problem is most likely either at lines 109 to 111 or lines 171 to 184 of the JS which I am including below:
The section that handles the touch events:
$(trackingLayer).on('mousedown touchstart', function(e) {
e.originalEvent.preventDefault();
isTracking = true;
curMouseX = curMouseY = -1;
if (curTool === "draw") {
var o = {};
o.painLevel = curPainLevel;
o.path = [];
DrawPoints.push(o);
}
}).on('mousemove touchmove', function(e) {
e.originalEvent.preventDefault();
trackMoveMouse($(this), e);
}).on('mouseup mouseleave touchend', function(e) {
e.originalEvent.preventDefault();
isTracking = false;
});
And the area that records the points:
var canvasOffset = ID.offset(); //or $(this).offset(); if you really just want the current element's offset
curMouseX = e.pageX - canvasOffset.left;
curMouseY = e.pageY - canvasOffset.top;
if (curMouseX !== -1 && prevMouseX !== -1) {
var o = {};
o.x = curMouseX / curZoom;
o.y = curMouseY / curZoom;
DrawPoints[DrawPoints.length - 1].path.push(o);
//log("Shapes Recorded: " + DrawPoints.length);
drawImage();
}
I have set up a jsfiddle for this: http://jsfiddle.net/nbernhard/dSED8/
Any help would be appreciated.
Thanks!
This question already has answers here:
Moveable/draggable <div>
(9 answers)
Closed 5 years ago.
I want to create a movable/draggable div in native javascript without using jquery and libraries. Is there a tutorial or anythign?
OK, here's my personal code that I use for lightweight deployments (projects where using a library is either not allowed or overkill for some reason). First thing first, I always use this convenience function so that I can pass either an id or the actual dom element:
function get (el) {
if (typeof el == 'string') return document.getElementById(el);
return el;
}
As a bonus, get() is shorter to type than document.getElementById() and my code ends up shorter.
Second realize that what most libraries are doing is cross-browser compatibility. If all browsers behave the same the code is fairly trivial. So lets write some cross-browser functions to get mouse position:
function mouseX (e) {
if (e.pageX) {
return e.pageX;
}
if (e.clientX) {
return e.clientX + (document.documentElement.scrollLeft ?
document.documentElement.scrollLeft :
document.body.scrollLeft);
}
return null;
}
function mouseY (e) {
if (e.pageY) {
return e.pageY;
}
if (e.clientY) {
return e.clientY + (document.documentElement.scrollTop ?
document.documentElement.scrollTop :
document.body.scrollTop);
}
return null;
}
OK, the two functions above are identical. There're certainly better ways to write them but I'm keeping it (relatively) simple for now.
Now we can write the drag and drop code. The thing I like about this code is that everything's captured in a single closure so there are no global variables or helper functions littering the browser. Also, the code separates the drag handle from the object being dragged. This is useful for creating dialog boxes etc. But if not needed, you can always assign them the same object. Anyway, here's the code:
function dragable (clickEl,dragEl) {
var p = get(clickEl);
var t = get(dragEl);
var drag = false;
offsetX = 0;
offsetY = 0;
var mousemoveTemp = null;
if (t) {
var move = function (x,y) {
t.style.left = (parseInt(t.style.left)+x) + "px";
t.style.top = (parseInt(t.style.top) +y) + "px";
}
var mouseMoveHandler = function (e) {
e = e || window.event;
if(!drag){return true};
var x = mouseX(e);
var y = mouseY(e);
if (x != offsetX || y != offsetY) {
move(x-offsetX,y-offsetY);
offsetX = x;
offsetY = y;
}
return false;
}
var start_drag = function (e) {
e = e || window.event;
offsetX=mouseX(e);
offsetY=mouseY(e);
drag=true; // basically we're using this to detect dragging
// save any previous mousemove event handler:
if (document.body.onmousemove) {
mousemoveTemp = document.body.onmousemove;
}
document.body.onmousemove = mouseMoveHandler;
return false;
}
var stop_drag = function () {
drag=false;
// restore previous mousemove event handler if necessary:
if (mousemoveTemp) {
document.body.onmousemove = mousemoveTemp;
mousemoveTemp = null;
}
return false;
}
p.onmousedown = start_drag;
p.onmouseup = stop_drag;
}
}
There is a reason for the slightly convoluted offsetX/offsetY calculations. If you notice, it's just taking the difference between mouse positions and adding them back to the position of the div being dragged. Why not just use the mouse positions? Well, if you do that the div will jump to the mouse pointer when you click on it. Which is a behavior I did not want.
You can try this
HTML
<div id="one" style="height:50px; width:50px; border:1px solid #ccc; background:red;">
</div>
Js Script for draggable div
window.onload = function(){
draggable('one');
};
var dragObj = null;
function draggable(id)
{
var obj = document.getElementById(id);
obj.style.position = "absolute";
obj.onmousedown = function(){
dragObj = obj;
}
}
document.onmouseup = function(e){
dragObj = null;
};
document.onmousemove = function(e){
var x = e.pageX;
var y = e.pageY;
if(dragObj == null)
return;
dragObj.style.left = x +"px";
dragObj.style.top= y +"px";
};
Check this Demo
This code corrects the position of the mouse (so the dragged object doesn't jump when you start dragging) and works with touch screens/phones as well
var dragObj = null; //object to be moved
var xOffset = 0; //used to prevent dragged object jumping to mouse location
var yOffset = 0;
window.onload = function()
{
document.getElementById("menuBar").addEventListener("mousedown", startDrag, true);
document.getElementById("menuBar").addEventListener("touchstart", startDrag, true);
document.onmouseup = stopDrag;
document.ontouchend = stopDrag;
}
function startDrag(e)
/*sets offset parameters and starts listening for mouse-move*/
{
e.preventDefault();
e.stopPropagation();
dragObj = e.target;
dragObj.style.position = "absolute";
var 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; //clientX and getBoundingClientRect() both use viewable area adjusted when scrolling aka 'viewport'
yOffset = e.targetTouches[0].clientY - rect.top;
window.addEventListener('touchmove', dragObject, true);
}
}
function dragObject(e)
/*Drag object*/
{
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";
}
}
function stopDrag(e)
/*End dragging*/
{
if(dragObj)
{
dragObj = null;
window.removeEventListener('mousemove', dragObject, true);
window.removeEventListener('touchmove', dragObject, true);
}
}
div{height:400px; width:400px; border:1px solid #ccc; background:blue; cursor: pointer;}
<div id="menuBar" >A</div>
<div draggable=true ondragstart="event.dataTransfer.setData('text/plain', '12345')">
drag me
</div>
<div ondragover="return false;" ondrop="this.innerHTML=event.dataTransfer.getData('text/plain')">
drop on me
</div>
How to make a element draggable without using jQuery UI?
I have this code:
<script type="text/javascript">
function show_coords(event)
{
var x=event.clientX;
var y=event.clientY;
var drag=document.getElementById('drag');
drag.style.left=x;
drag.style.top=y
}
</script>
<body style="height:100%;width:100%" onmousemove="show_coords(event)">
<p id="drag" style="position:absolute">drag me</p>
</body>
The problem is that I want to drag while the user the pressing the mouse button. I tried onmousedown but results were negative.
It will be quite easy as you get the concept.
function enableDragging(ele) {
var dragging = dragging || false, //Setup a bunch of variables
x, y, Ox, Oy,
enableDragging.z = enableDragging.z || 1,
current;
ele.onmousedown = function(ev) { //When mouse is down
current = ev.target;
dragging = true; //It is dragging time
x = ev.clientX; //Get mouse X and Y and store it
y = ev.clientY; // for later use.
Ox = current.offsetLeft; //Get element's position
Oy = current.offsetTop;
current.style.zIndex = ++enableDragging.z; //z-index thing
window.onmousemove = function(ev) {
if (dragging == true) { //when it is dragging
var Sx = ev.clientX - x + Ox, //Add the difference between
Sy = ev.clientY - y + Oy; // 2 mouse position to the
current.style.top = Sy + "px"; // element.
current.style.left = Sx + "px";
return false; //Don't care about this.
}
};
window.onmouseup = function(ev) {
dragging && (dragging = false); //Mouse up, dragging done!
}
};
}
enableDragging(document.getElementById("drag")); //draggable now!
var ele = document.getElementsByTagName("div");
for(var i = 0; i < ele.length; i++){ //Every div's is draggable
enableDragging(ele[i]); // (only when its "position"
} // is set to "absolute" or
// "relative")
http://jsfiddle.net/DerekL/NWU9G/
The reason why your code is not working is because the <div> will always follow where your cursor goes, and you are not actually dragging it. The top left corner will always follow your cursor, and this is not we wanted.
UPDATE
Now if you only want a grabber or something similar, just change this part of the script:
ele.onmousedown = function(ev) {
current = ev.target;
to
var grabber = document.createElement("div");
grabber.setAttribute("class", "grabber");
ele.appendChild(grabber);
grabber.onmousedown = function(ev) {
current = ev.target.parentNode;
Now you can only click on the grabber to start the dragging process.
http://jsfiddle.net/DerekL/NWU9G/7/