I've been having trouble coming up with a way of making a drag and drop area on a web page. I have multiple resizable <div>s, and I want to be able to drag these anywhere. Think of it like dragging desktop icons around the desktop and placing them anywhere. It would be nice if I could add buttons to these <div>s to change their z-indexes and have them overlap. Would this require use of <canvas>? I am currently using <section> for the drag area.
Thanks!
If you want to do the drag-n-drop yourself, you may want to have one div enclosing the draggable div, so you can use the top of the larger div as the draggable area.
So, you have
<div id='draggablediv' style='backgroundcolor: blue;'>
<div class='draggable' style='position: relative; top: 5em; left: 0em;'>...
</div></div>
This code is purely for example, won't work, btw.
So, on the draggablediv you would put an onclick event handler, and this would start an onmousemove handler and onmouseup handler. The last one is to drop, but you may also want to have onblur in case the mouse moves outside of the browser.
Then, as the mouse moves, just reposition the div, so these divs would need to be absolute positioned, or relative positioned (absolute would be easier).
It is important to remove the event handlers by setting them to null when the mouse button is released.
If not in a droppable area then make certain to put the div back where it started, so you will want a closure so you can remember the original top/left coordinates of the div.
You will want to get familiar with this functionality:
(function g(someval) {
var a = someval;
return h() {
}
})(origval);
For an example search for getImgInPositionedDivHtml in http://jibbering.com/faq/notes/closures/
In order to change the z-index you may want to have a +/- in the div and when that is clicked on the z-index is changed.
Here is a page that talks about changing the z-index.
http://msdn.microsoft.com/en-us/library/ms533005(v=vs.85).aspx
I don't think you can do that with HTML-Only, however this is some example of how you could do it with javascript:
<html>
<head>
<style>
.draggable {
position: absolute;
cursor: default;
background-color: purple;
top: 0px;
left: 0px;
}
</style>
</body>
<body onmouseup="stopMovement()">
<div id="draggable" class="draggable" onmousedown="startMovement(event)">
Drag me around :D
</div>
<script>
var drg = document.getElementById("draggable");
var xDisplacement = 0;
var yDisplacement = 0;
function startMovement(e) {
xDisplacement = e.pageX - getComputedStyle(drg).left.substring(0, getComputedStyle(drg).left.length - 2);
yDisplacement = e.pageY - getComputedStyle(drg).top.substring(0, getComputedStyle(drg).top.length - 2);
document.body.onmousemove = moveDraggable;
}
function stopMovement() {
document.body.onmousemove = null;
}
function moveDraggable(e) {
drg.style.top = e.pageY - yDisplacement;
drg.style.left = e.pageX - xDisplacement;
}
</script>
</body>
</html>
Related
I have a little thumbnail that represents all the window. You can move div#maquetaPant and the window should to scroll at the same time you move the little square.
It's easier If you try:
http://www.noteboardapp.com/boarddemo
Drag the little square on the mini map on top right.
The code is here. If I put the function "dragMaqueta" in the stop event, then it works well. But I want it in the drag event to scroll the window at the same time of dragging the square. But if you try you'll see that doesn't work. It seems that window.scrollTo(scrollX,scrollY) moves the square outside the container.
<div id="canvasDiv">
<canvas id="canvas" width="125" height="100"></canvas>
<div id="maquetaPant"></div>
</div>
#maquetaPant
{
position: absolute;
}
$("#maquetaPant").draggable({containment: '#canvasDiv',drag: dragMaqueta});
function dragMaqueta(evt,ui)
{
var scrollX = parseInt(ui.position.left / $('#canvasDiv').width() * $('.Postits').width());
var scrollY = parseInt(ui.position.top / $('#canvasDiv').height() * $('.Postits').height());
window.scrollTo(scrollX,scrollY);
}
Do you know how to solve it?
Thank you!
I have a page with an embedded youtube video, and I'm trying to implement a custom overlay where you can define areas using a resizable and draggable <div> (using JQuery UI).
When dragging the <div> in other areas of the screen, it's perfectly responsive, but when over the video (embedded using the IFrame API, incase it matters), if you move the mouse at anything other than a crawl, it will regularly 'lose its grip' on the resize handles or the move handle. This is the case in both IE and Chrome.
JSFiddle here: http://jsfiddle.net/MfZes/1/ (draggable box is below the youtube frame)
Does anyone know why this is, or if it's avoidable?
Thanks in advance.
I've done this before.
You can hook onto the dragstart, resizestart, dragstop and resizestop events of jquery ui's resizeable and draggable plugins.
Put the video in a container div. Alongside the video, insert another div which will act as an overlay. Set the width and height to 100%, position it absolutely and set the display to hidden.
When the resize/drag start events fire, show the overlay div. When they stop, hide it. (You need to hide it as you still want to be able to interact with the video when you're not resizing or dragging.
I had the same problem but with hover on canvas:
$('.DraggableDiv').draggable({
start : function() {
var d = document.createElement('div');
$(d).addClass('canvas_shadow');
$('.canvasContainer').append(d);
},
stop : function() {
$( ".canvas_shadow" ).remove();
});
add css for .canvas_shadow:
.canvas_shadow {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
opacity: 0.1;
z-index: 80;
}
I think it would be cool to set a custom cursor click effect with jQuery. Something similar to Android Incredible 2 browser where it highlights click-able items in green when selected. Except mine would be the cursor with a box around it something like 1px width, very subtle, and it would kind of float/toggle until you point over a clickable item - and then it would kind of 'lock' in.
I've found something like this that was done that fired a bunch of squares on clicks, but I can't relocate where I found it - and it was a huge amount of JavaScript, is this possible with jQuery - and would this be a bad idea for the users experience?
You can use CSS to change cursor, and with JavaScript events you can change your cursor whenever you want. Here is an example:
<style>
.cursor1 { cursor: pointer; }
.cursor2 { cursor: url(myCur.cui); }
</style>
<script>
var mydiv = document.getElementById("myDiv");
mydiv.onmousedown = function(e) {
e.target.classList.add("cursor2");
}
mydiv.onmouseup = function(e) {
e.target.classList.remove("cursor2");
}
</script>
<div id="myDiv" class="cursor1"> Here is my text!! </div>
Also, you can use JQuery.
How can I make a picture follow the mouse in a specific <div>?
I know that I can get the mouse position from e.pageX & e.pageY and with the code document.onmousemove = followmouse;. Run the followmouse function every moment the mouse move in a page and in the followmouse function, set the picture position to the mouse position. For the exact question I asked here (how can I make a picture follow the mouse in a specific <div>), I have this idea:
Get my div top, left, width, and height and do some math and if mouse go out of the div, set visibility:hidden for the picture.
But isn't there any simple way to do this?
Let's assume you have some HTML like this,
<div id="mydiv" style="width: 300px; height: 300px;"></div>
<img id="myimg" style="position: absolute;" alt="" />
then
document.getElementById("mydiv").onmousemove = function(e) {
document.getElementById("myimg").style.top = e.pageY*1 + 5 + "px";
document.getElementById("myimg").style.left = e.pageX*1 + 5 + "px";
}
would move your picture to the mouse only if the mouse is over the div.
So long as the picture is actually contained in the div and you move it relative to its normal position, then I think setting overflow:hidden on the containing div should work. When I say "setting", I don't mean every time the mouse moves outside, but just once in the main CSS.
The site I'm working on has a collection of navigation elements across the top ("Products", "Company", etc.). When you mouse over the Products link, an overlay appears that shows a list of products with links to each. There's a small link at the top of the container that, when clicked, closes the container. All of this works as advertised.
The client has asked that, once a user's mouse pointer is a sufficient distance from the overlay element, the overlay element would close (without them having to click the 'close' link). This element appears on multiple pages that have disparate content, so I'm afraid it won't be as simple as adding a mouseover listener to another single element within the page and have it work everywhere. My question, I suppose, is this: is there a relatively easy way to know when the mouse cursor is x pixels away from this container and trigger an event when this occurs?
My other thought is that I could just find several elements on the page that fit this criteria and add mouseover listeners to each, but I'm assuming there's a more elegant way of handling this.
Thanks in advance - and please let me know if more detail is needed.
Here's one example.
http://jsfiddle.net/CsgFk/
Calculate the bounds you want around the overlay, and set up a mousemove hanlder on the document, which tests to see if the mouse is outside the bounds.
EDIT: It may be worthwhile to unbind the mousemove from the document when the overlay is hidden, and rebind it when revealed so that the mousemove isn't constantly firing for no reason. Or at the very least, have the mousemove handler check to see if the overlay is already hidden before hiding it.
HTML
<div id='overlay'></div>
CSS
#overlay {
width: 200px;
height: 200px;
background: orange;
position: relative;
top: 123px;
left:23px;
}
jQuery
var $ovl = $('#overlay');
var offset = $ovl.offset();
var height = $ovl.height();
var width = $ovl.width();
var bounds = {top: offset.top - 100,
bottom: offset.top + height + 100,
left: offset.left - 100,
right: offset.left + width + 100
}
$ovl.mouseenter(function() {
$ovl.stop().animate({opacity:1});
});
$(document).mousemove(function(e) {
if(e.pageX < bounds.left ||
e.pageX > bounds.right ||
e.pageY < bounds.top ||
e.pageY > bounds.bottom) {
$ovl.stop().animate({opacity:.3});
}
});
EDIT:
Here's another idea (although it is heavily dependent on your layout). Place the overlay inside a container that has a large padding and remove the overlay when the pointer performs a mouseleave on the container. Again, this may not be feasible in your layout.
EDIT:
One other idea would be to set a delay on the code used to remove the overlay. Its not as precise, but may yield a sufficiently desirable effect.
Why not use a mouseout event with a timer?
var zGbl_OverlayCloseTimer = '';
OverlayElement.addEventListener ("mouseout", CloseOverlayWithDelay, false);
function CloseOverlayWithDelay (zEvent)
{
if (typeof zGbl_OverlayCloseTimer == "number")
{
clearTimeout (zGbl_OverlayCloseTimer);
zGbl_OverlayCloseTimer = '';
}
zGbl_OverlayCloseTimer = setTimeout (function() { CloseOverlay (); }, 333);
}
function CloseOverlay ()
{
...
}