I'm attempting to drag an object using dojo.dnd but want the avatar to be in the same position as the object was (relative to the mouse)
i.e. if a person clicks in the middle of the object then the mouse cursor will be in the middle of the avatar.
I've had all sorts of strange results.
if i connect a function to body.onmousemove the drop part of the dnd fails.
How can i get this working?
<html>
<head>
<title>DnD Events</title>
<style type="text/css">
.target
{
border: 1px dotted gray;
width: 300px;
height: 300px;
padding: 5px;
-moz-border-radius: 8pt 8pt;
radius: 8pt;
}
.source
{
border: 1px dotted skyblue;
height: 200px;
width: 300px;
-moz-border-radius: 8pt 8pt;
radius: 8pt;
}
.dojoDndItemOver
{
background: #feb;
border: 1px dotted gray;
}
.target .dojoDndItemAnchor
{
background: #ededed;
border: 1px solid gray;
}
.dojoDndAvatarHeader {
display: none;
}
</style>
<script type="text/javascript" src="dojo/dojo.js" djconfig="parseOnLoad: true, isDebug:false"></script>
<script type="text/javascript">
dojo.require("dojo.dnd.Source");
dojo.require("dojo.dnd.Container");
dojo.require("dojo.dnd.Moveable");
dojo.require("dojo.dnd.Manager");
dojo.require("dojo.dnd.Avatar");
var mouse = { x: 0, y: 0 , handle:undefined};
function mouseCoords(ev) {
var px, py;
ev = ev || window.event;
if (ev.pageX || ev.pageY) {
px = ev.pageX; py = ev.pageY;
} else {
px = ev.clientX + dojo.body().scrollLeft - dojo.body().clientLeft;
py = ev.clientY + dojo.body().scrollTop - dojo.body().clientTop;
}
mouse = { x: px, y: py };
// dojo.byId("msg").innerHTML = dojo.toJson(mouse);
}
//dnd WORKS when following lines are commented out. (positioning fails)
var mchandle = dojo.connect(document, "onmousemove", 'mouseCoords');
//dojo.query(".dojoDndItem").connect("onclick", 'mouseCoords');
//dojo.dnd.Source.onMouseDown('mouseCoords')
</script>
<script type="text/javascript">
var item_price;
var total = 0;
function AddItems(target, nodes) {
for (var i = 0; i < nodes.length; i++)
{ total += parseFloat((target.getItem(nodes[i].id)).data); }
dojo.byId("cost").innerHTML = total;
}
function SubstractItems(target, nodes) {
for (var i = 0; i < nodes.length; i++) {
total -= parseInt((target.getItem(nodes[i].id)).data);
}
dojo.byId("cost").innerHTML = total;
}
function ShowPrice(target, nodes) {
var sum = 0;
for (var i = 0; i < nodes.length; i++) {
dojo.dnd.manager().OFFSET_X = 0 - (mouse.x - dojo._abs(nodes[i]).x);
dojo.dnd.manager().OFFSET_Y = 0 - (mouse.y - dojo._abs(nodes[i]).y);
dojo.dnd.manager().updateAvatar();
sum += parseInt((target.getItem(nodes[i].id)).data);
}
dojo.byId("msg").innerHTML = "Selected Item Price is $" + sum;
}
function ClearMsg()
{ dojo.byId("msg").innerHTML = ""; }
function init() {
dojo.subscribe("/dnd/drop", function(source, nodes, iscopy) {
var t = dojo.dnd.manager().target;
ClearMsg();
if (t == source) { return; }
if (t == cart) { AddItems(t, nodes); }
if (t == shelf) { SubstractItems(t, nodes); }
});
dojo.subscribe("/dnd/start", function(source, nodes, iscopy) {
ShowPrice(source, nodes);
});
dojo.subscribe("/dnd/cancel", function() {
ClearMsg();
});
}
dojo.addOnLoad(init);
</script>
</head>
<body style="font-size: 12px;">
<table>
<tbody>
<tr valign="top">
<td>
SOURCE
<div dojotype="dojo.dnd.Source" jsid="shelf" class="source" id="source1" accept="red,blue"
singular="false">
<img src="BLUE.png" class="dojoDndItem" dndtype="blue" dnddata="10" title="$10" />
<img src="RED.png" class="dojoDndItem" dndtype="red" dnddata="60" title="$60" />
<img src="BLUE.png" class="dojoDndItem" dndtype="blue" dnddata="13" title="$13" />
<img src="RED.png" class="dojoDndItem" dndtype="red" dnddata="15" title="$15" />
<img src="BLUE.png" class="dojoDndItem" dndtype="blue" dnddata="3" title="$3" />
<img src="RED.png" class="dojoDndItem" dndtype="red" dnddata="148" title="$148" />
<img src="BLUE.png" class="dojoDndItem" dndtype="blue" dnddata="1" title="$1" />
<img src="RED.png" class="dojoDndItem" dndtype="red" dnddata="10" title="$10" />
<img src="BLUE.png" class="dojoDndItem" dndtype="blue" dnddata="3" title="$3" />
</div>
</td>
<td>
TARGET
<div dojotype="dojo.dnd.Source" jsid="cart" class="target" accept="red,blue" id="target1">
</div>
</td>
<td>
Total Price (USD): <span id="cost">0.00</span><br />
<b>Message: <span id="msg" style="color: blue"></span></b>
<td>
</tr>
<tbody />
</table>
</body>
</html>
Dojo's DND is a limited in this sense. The avatar is positioned offset so the move events are not trapped by the node representing the drag. Typical source/targets will not work in this case. I have created a hybrid "mover/source" dnd example that may help you along with what you are trying to accomplish:
http://svn.dojotoolkit.org/src/demos/trunk/beer/src/dnd.js
Basically, we connect "mousedown" to some node. When that is fired, we create a clone of that node directly over where the the original node is in the page (see _dragStart function). Then, we register temporary mousemove and mouseup event listeners. mousemove is a tight function optimized for speed. simply set the top/left position of the "avatar" (the clone) relative to e.pageX and e.pageY (normalized event object parts).
when mouseup is fired, we disconnect both mouseup and mousemove events (this._listeners). In the sample the "overTarget" function simply returns true. You can change this logic to be whatever you need to ensure the current pageX/pageY coords are within a bounding box of your choice (a Source/Target, whatever, however you like).
In the example, I have it animating back to the original x/y of the "source", or turning it into a dojo.dnd.Moveable (it being the cloned node), creating a sort of markupfactory out of the source. You will likely want to just use this to add whatever data to your cart, and destroy the avatar.
Hope this helps.
For the time being...(since i didn;t know how to implement the hybrid js)
i've utilised the cancel event and compared the mouse coords to each source object on the page to determine which one it's was intended to be dropped into.
JS in page is now:
var mchandle;
dojo.require("dojo.dnd.Source");
var lastSrc;
function init() {
dojo.subscribe("/dnd/drop", function(source, nodes, iscopy) {
dojo.byId("msg").innerHTML += " drop";
dojo.disconnect(mchandle);
});
dojo.subscribe("/dnd/start", function(source, nodes, iscopy) {
lastSrc = source;
mchandle = dojo.connect(dojo.doc, "onmousemove", "mouseCoords");
dojo.byId("msg").innerHTML = "start";
var px = 0;
var py = 0;
for (var i = 0; i < nodes.length; i++) {
var nPos = dojo._abs(nodes[i]);
px = nPos.x > px ? nPos.x : px;
py = nPos.y > py ? nPos.y : py;
}
dojo.dnd.manager().OFFSET_X = 0 - (source._lastX - px);
dojo.dnd.manager().OFFSET_Y = 0 - (source._lastY - py);
});
dojo.subscribe("/dnd/cancel", function() {
dojo.byId("msg").innerHTML += " cancel";
dojo.query("[dojotype=\"dojo.dnd.Source\"]").forEach(function(node, index, array) {
var elemXY = dojo.coords(node);
if ( //in source box
(elemXY.x <= document.mouse.x && document.mouse.x <= (elemXY.x + elemXY.w)) && (elemXY.y <= document.mouse.y && document.mouse.y <= (elemXY.y + elemXY.h))) {
var s = new dojo.dnd.Source(node, null);
s.insertNodes(true, lastSrc.getSelectedNodes(), null, null);
}
});
dojo.disconnect(mchandle);
lastSrc = null;
});
}
dojo.addOnLoad(init);
function mouseCoords(ev) {
var px, py;
ev = ev || window.event;
if (ev.pageX || ev.pageY) {
px = ev.pageX;
py = ev.pageY;
} else {
px = ev.clientX + dojo.body().scrollLeft - dojo.body().clientLeft;
py = ev.clientY + dojo.body().scrollTop - dojo.body().clientTop;
}
document.mouse = {
"x": px,
"y": py
};
}
A Bug is still occurring.
I drag to the target (all is well.)
i drag from the target and a duplicate avatar is stuck on the screen.
firebug reports an error.
_5.getItem(_6[i].id) is undefined
} catch (e) {\r\n dojo.js (line 203)
could you offer any help?
Related
<!doctype html>
<html>
<head>
<title>Get home</title>
<style>
table {
border-collapse: collapse;
}
td {
border: solid 1px #888;
width: 30px;
height: 30px;
font-family: sans-serif;
font-size: calc(30px/4.0 + 1px);
text-align: center;
}
.cell0 {
background: #88ff99;
}
.cell1 {
background: #116615;
}
.player {
background: #e11;
}
.home {
background: white;
}
.status {
font-size: 15pt;
font-family: Arial;
}
</style>
<script>
// Will be initialised to a 2-dimensional array
var gameBoard = [];
// Size of game
var size = 10;
// Current fuel and supply
var fuel = 20;
var supply = 0;
// Current position of player (start in the bottom-right)
var positionX = size - 1;
var positionY = size - 1;
// Whether we are playing the game
var playing = true;
// Use this function to make a move where x and y represent the direction of
// a move, e.g.
// move(-1, 0) means going left
// move(1, 0) means going right
// move(0, -1) means going up
// move(0, 1) means going down
function move(x, y) {
//
if (positionX + x < size && positionX + x >= 0 &&
positionY + y < size && positionY + y >= 0) {
// Move is within the board
}
}
// Use this function to update the status
function updateStatus() {
document.getElementById("fuel").innerHTML = fuel;
document.getElementById("store").innerHTML = supply;
}
function setup() {
// Set the gameboard to be empty
gameBoard = [];
var board = document.getElementById("board");
for (var i = 0; i < size; i++) {
// Create a new row of the game
var htmlRow = document.createElement("tr");
board.appendChild(htmlRow);
var row = []
for (var j = 0; j < size; j++) {
// Chose a random type of cell
var type = Math.round(Math.random());
var cell = document.createElement("td");
cell.className = "cell" + type;
// Add the cell to the row
htmlRow.appendChild(cell);
row.push(cell);
}
gameBoard.push(row);
}
// Setup the player
gameBoard[size-1][size-1].className = "player";
// Setup the home
gameBoard[0][0].className = "home";
gameBoard[0][0].innerHTML = "HOME";
// Register the listener and update the state
updateStatus();
document.body.addEventListener("keydown", keyEvent);
}
</script>
</head>
<body onLoad="setup();">
<div class="status">Fuel: <span id="fuel"></div>
<div class="status">Store: <span id="store"></div>
<table id="board"></table>
<div class="status" id="outcome"></div>
</body>
</html>
I'm creating a simple game on HTML, and I can't think of how to get the move function to work, while it automatically updates the game and the map, is anyone able to help. I'm new to coding and I genuinely cant fathom what code to put in to make the move function work, whether it be using arrow keys or creating buttons to make the entity move.
Without making too many changes to the way you have things set up, I added a function that will add the "player" class to elements based on "wsad" or arrow key presses.
<!doctype html>
<html>
<head>
<title>Get home</title>
<style>
table {
border-collapse: collapse;
}
td {
border: solid 1px #888;
width: 30px;
height: 30px;
font-family: sans-serif;
font-size: calc(30px/4.0 + 1px);
text-align: center;
}
.cell0 {
background: #88ff99;
}
.cell1 {
background: #116615;
}
.player {
background: #e11;
}
.home {
background: white;
}
.status {
font-size: 15pt;
font-family: Arial;
}
</style>
<script>
// Will be initialised to a 2-dimensional array
var gameBoard = [];
// Size of game
var size = 10;
// Current fuel and supply
var fuel = 20;
var supply = 0;
// Current position of player (start in the bottom-right)
var positionX = size - 1;
var positionY = size - 1;
// Whether we are playing the game
var playing = true;
function move(direction) {
let x = positionX;
let y = positionY;
switch (direction) {
case "left":
x--;
break;
case "right":
x++;
break;
case "up":
y--;
break;
case "down":
y++;
break;
}
const validMove =
x < size &&
x >= 0 &&
y < size &&
y >= 0;
if (!validMove) return console.error(
"What are you trying to do?" + "\n" +
"Break the implied rules of a game?" + "\n" +
"I expect more from you" + "\n" +
"That's a wall you dummy!"
);
positionX = x;
positionY = y;
gameBoard[y][x].classList.add("player");
}
// Use this function to update the status
function updateStatus() {
document.getElementById("fuel").innerText = fuel;
document.getElementById("store").innerText = supply;
}
function keyEvent(e) {
const keyMoveDict = {
"ArrowLeft": "left",
"ArrowRight": "right",
"ArrowUp": "up",
"ArrowDown": "down",
"a": "left",
"d": "right",
"w": "up",
"s": "down",
}
const movement = keyMoveDict[e.key];
if (movement) move(movement);
}
function setup() {
// Set the gameboard to be empty
gameBoard = [];
var board = document.getElementById("board");
for (var i = 0; i < size; i++) {
// Create a new row of the game
var htmlRow = document.createElement("tr");
board.appendChild(htmlRow);
var row = []
for (var j = 0; j < size; j++) {
// Chose a random type of cell
var type = Math.round(Math.random());
var cell = document.createElement("td");
cell.className = "cell" + type;
// Add the cell to the row
htmlRow.appendChild(cell);
row.push(cell);
}
gameBoard.push(row);
}
// Setup the player
gameBoard[size-1][size-1].className = "player";
// Setup the home
gameBoard[0][0].className = "home";
gameBoard[0][0].innerHTML = "HOME";
// Register the listener and update the state
updateStatus();
document.body.addEventListener("keydown", keyEvent);
}
</script>
</head>
<body onLoad="setup();">
<div class="status">Fuel: <span id="fuel"></span></div>
<div class="status">Store: <span id="store"></span></div>
<table id="board"></table>
<div class="status" id="outcome"></div>
</body>
</html>
Thanks to a really helpful user on this website (whose name I do not know, but I wish to thank and credit him!), I got the following tip on how to store area elements in an array so that when I mouse over a coordinate, I could display all of the overlay id's of the area elements that existed at that coordinate (even if the area elements were not at the same z-level):
I'm just stuck on one thing- once I have gathered all the elements that exist at the coordinate in the hoveredElements array, how do I show their overlay ids?
EDIT:
Here is an example of the full code (the overlay still does not display when I mouse over)
The file test.txt contains:
cscCSL1A15 700 359 905 318
cscCSL1A14 794 400 905 318
I use the maphilight plugin available online, and blanketaphi.png is the plot I use as a background.
<!DOCTYPE html>
<html>
<head>
<title>Detector Elements</title>
<script type="text/javascript"
src="Demo_imagemap_highlight_files/jquery-1.js"></script>
<!-- add maphilight plugin -->
<script type="text/javascript"
src="Demo_imagemap_highlight_files/jquery_002.js"></script>
</head>
<body>
<div class="content">
<div class="map"
style='display: block; background: transparent
url("Demo_imagemap_highlight_files/blanketaphi.png")
repeat scroll 0% 0%; position: relative; padding: 0px; width: 1037px;
height: 557px;'>
<canvas width="1037" height="557" style="width: 1037px; height: 557px;
position: absolute; left: 0px; top: 0px; padding: 0px; border: 0px none;
opacity: 1;"></canvas>
<img style="opacity: 0; position: absolute; left: 0px; top: 0px; padding: 0px;
border: 0px none;" src="Demo_imagemap_highlight_files/blanketaphi.png"
alt="foo" class="map maphilighted" usemap="#demo" height="557" width="1037"
border="0" />
</div>
</div>
<map name="demo" id="demo"></map>
</body>
</html>
<script type="text/javascript">
window.onload = function(){
var f = (function(){
var xhr = [];
var files = [ "test.txt"];
for (i = 0; i < 1; i++) {
(function (i){
xhr[i] = new XMLHttpRequest();
xhr[i].open("GET", files[i], true);
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
// get text contents
j=20000*i + 50000;
var coords = xhr[i].responseText.split("\n");
coords = coords.filter(Boolean) //prevents extra rect with 0 coords
coords.forEach(function(coord) {
var area = document.createElement("area");
var att = document.createAttribute("data-maphilight");
if (i == 0) { //green
att.value = '{"strokeColor":"000000","strokeWidth":2,' +
'"fillColor":"009900","fillOpacity":0.5}';
}
area.setAttributeNode(att);
area.id = "r"+j;
area.shape = "rect";
area.coords = coord.substring(10,coord.length).trim()
.replace(/ +/g,","); // replaces spaces in txt file with commas
area.href = "#";
area.alt = "r"+j;
// create overlay with first term in string
var div = document.createElement("div");
div.id ="overlayr"+j;
div.innerHTML = coord.substring(0,10);
div.style.display = "none";
//increase j
j++;
// get map element
document.getElementById("demo").appendChild(area);
document.getElementById("demo").appendChild(div);
});
$('.map').maphilight();
//display overlay ids by mousing over
var elementPositions = [];
var hoveredElements = [];
if($('#demo')) {
$('#demo area').each(function() {
var offset = $(this).offset();
var top = offset.top;
var left = offset.left;
var bottom = $(window).height() - top - $(this).height();
var right = $(window).width() - left - $(this).width();
elementPositions.push({
element: $(this),
top: top,
bottom: bottom,
left: left,
right: right
});
//alert(top + "," + left + "," + right + "," + bottom);
});
$("body").mousemove(function(e) {
hoveredElements = [];
var yPosition = e.pageX;
var xPosition = e.pageY;
for (var i = 0; i < elementPositions.length; i++) {
if (xPosition >= elementPositions[i].left &&
xPosition <= elementPositions[i].right &&
yPosition >= elementPositions[i].top &&
yPosition <= elementPositions[i].bottom) {
// The mouse is within the element's boundaries
$("#hovers").append(elementPositions[i].element);
}
}
for (var i = 0; i < hoveredElements.length; i++) {
// The element as a jQuery object
var elem = hoveredElements[i];
var id = hoveredElements[i].attr('id');
$('#overlay'+id).show();
}
});
};
}
};
xhr[i].send();
})(i);
}
})();
};
</script>
Why not just something like this:
var elementPositions = [];
var hoveredElements = [];
if($('#demo')) {
$('#demo area').each(function() {
var offset = $(this).offset();
var top = offset.top;
var left = offset.left;
var bottom = $(window).height() - top - $(this).height();
var right = $(window).width() - left - $(this).width();
elementPositions.push({ element: $(this), top: top, bottom: bottom, left: left, right: right });
//alert(top + "," + left + "," + right + "," + bottom);
});
$("body").mousemove(function(e) {
hoveredElements = [];
var yPosition = e.pageX;
var xPosition = e.pageY;
for (var i = 0; i < elementPositions.length; i++) {
if (xPosition >= elementPositions[i].left &&
xPosition <= elementPositions[i].right &&
yPosition >= elementPositions[i].top &&
yPosition <= elementPositions[i].bottom) {
// The mouse is within the element's boundaries
hoveredElements.push(elementPositions[i].element);
$("#hovers").append(elementPositions[i].element);
}
} //end of for loop over all elements
console.log(hoveredElements);
for (var i = 0; hoveredElements.length; i++)
{ //for loop over all hovered elements
// The element as a jQuery object
var elem = hoveredElements[i];
var id = hoveredElements[i].attr('id');
console.log(id);
$('#overlay'+id).show();
// Do stuff to that jQuery element:
//??? something like elem.show();
}
You've got a lot of stuff here that doesn't make sense to me but here's what I can gather so far.
Your areas need to be in a container called demo area. Not sure how the space in the ID works so in my case I switched it to demoarea. Also somewhere in the page, there has to be another element called demo for anything to even happen.
Once that's done, the script loads demoarea into the elementPositions array. Judging from your description that's not what you want to do, you probably want to load all the elements inside demoareainto the array. So the first change is
$('#demo area').each(function() {
Becomes
$('#demoarea').children().each(function() {
Now what becomes confusing to me is that this script for whatever reason decides that you need to have another element called hover so it can move the element out of demoarea into hover when you mouse over it. If that is what you want, then you can do your show trick with some simple CSS.
<div style="display:none" id="overlayr6064"> Example Overlay ID name </div>
Becomes
<div id="overlayr6064"> Example Overlay ID name </div>
And then you add:
<style>
#demoarea div {
display: none;
}
#hover div {
display: block;
}
</style>
Assuming that is not what you wanted, what #liamEgan did to add the elements to the hoveredElements array is good, but you have an infinite loop here
for (var i = 0; hoveredElements.length; i++)
it should be
for (var i = 0; i < hoveredElements.length; i++)
Then the rest works... except one last thing, you want to load these listeners to your script when the page loads in a document ready method.
So in all it looks a bit like:
//display overlay ids by mousing over (my map is called 'demo')
var elementPositions = [];
var hoveredElements = [];
if($('#demo')) {
$('#demoarea').children().each(function() {
var offset = $(this).offset();
var top = offset.top;
var left = offset.left;
var bottom = $(window).height() - top - $(this).height();
var right = $(window).width() - left - $(this).width();
elementPositions.push({ element: $(this), top: top, bottom: bottom, left: left, right: right });
});
console.log('After Scanning demoarea elementPositions looks like:')
console.log(elementPositions);
$(document).ready(function () {
$("body").mousemove(function(e) {
hoveredElements = [];
var yPosition = e.pageX;
var xPosition = e.pageY;
for (var i = 0; i < elementPositions.length; i++) {
if (xPosition >= elementPositions[i].left &&
xPosition <= elementPositions[i].right &&
yPosition >= elementPositions[i].top &&
yPosition <= elementPositions[i].bottom) {
// The mouse is within the element's boundaries
if (typeof elementPositions[i].element != "undefined") {
hoveredElements.push(elementPositions[i].element);
$("#hovers").append(elementPositions[i].element);
}
}
} //end of for loop over all elements
for (var i = 0; i < hoveredElements.length; i++) { //for loop over all hovered elements
// The element as a jQuery object
console.log(hoveredElements[i]);
if (typeof hoveredElements[i] != "undefined") {
var elem = hoveredElements[i];
var id = elem.attr('id');
$('#overlay'+id).show();
}
// Do stuff to that jQuery element:
//??? something like elem.show();
}
});
});
}
#demoarea {
border: 2px blue dotted;
}
/* Border added so I can see where to mouse over */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="demo">
<div id="demoarea">
<area shape="rect" coords="431,499,458,491" href="#" id="r6064" alt="r6064">
<div style="display:none" id="overlayr6064"> Example Overlay ID name </div>
</div>
<div id="hovers">
</div>
</div>
Edit: sorry I added the undefined tests while fixing this because of the infinite loop but I think they're not really needed. Still nice to have though. Also since the area also gets moved into the hover area this script does try to show an element called overlayoverlayr6064r6064 which fortunately doesn't exist. But ya, again, probably not what you had in mind.
I am trying this code but i get: document.getElementsByName(...).style is undefined
I have also a problem with the delegation, i think. Any help?
<html>
<head>
<style type="text/css">
#toolTip {
position:relative;
width:200px;
margin-top:-90px;
}
#toolTip p {
padding:10px;
background-color:#f9f9f9;
border:solid 1px #a0c7ff;
-moz-border-radius:5px;-ie-border-radius:5px;-webkit-border-radius:5px;-o-border-radius:5px;border-radius:5px;
}
#tailShadow {
position:absolute;
bottom:-8px;
left:28px;
width:0;height:0;
border:solid 2px #fff;
box-shadow:0 0 10px 1px #555;
}
#tail1 {
position:absolute;
bottom:-20px;
left:20px;
width:0;height:0;
border-color:#a0c7ff transparent transparent transparent;
border-width:10px;
border-style:solid;
}
#tail2 {
position:absolute;
bottom:-18px;
left:20px;
width:0;height:0;
border-color:#f9f9f9 transparent transparent transparent;
border-width:10px;
border-style:solid;
}
</style>
<script type='text/javascript'>
function load () {
var elements = document.getElementsByName('toolTip');
for(var i=0; i<elements.length; i++) {
document.getElementsByName(elements[i]).style.visibility = 'hidden';
}
}
</script>
</head>
<body onload="load()">
<br><br><br><br><br><br><br><br><br><br><br><br>
<a class="hd"
onMouseOver="document.getElementsByName('toolTip')[0].style.visibility = 'visible'"
onmouseout ="document.getElementsByName('toolTip')[0].style.visibility = 'hidden'">aqui</a>
<div id="toolTip" name="toolTip">
<p>i can haz css tooltip</p>
<div id="tailShadow"></div>
<div id="tail1"></div>
<div id="tail2"></div>
</div>
<br><br><br>
<a class="hd"
onMouseOver="document.getElementsByName('toolTip')[0].style.visibility = 'visible'"
onmouseout ="document.getElementsByName('toolTip')[0].style.visibility = 'hidden'">aqui</a>
<div id="toolTip" name="toolTip">
<p>i can haz css tooltip</p>
<div id="tailShadow"></div>
<div id="tail1"></div>
<div id="tail2"></div>
</div>
</body>
</html>
demo
Try changing the id toolTip to a class:
<div class="toolTip">...</div>
And change your JS to use the display style-thing, rather than visibility, nd the onmouseover's are best dealt with using JS event delegation:
function load()
{
var i, tooltips = document.getElementsByClassName('toolTip'),
mouseOver = function(e)
{//handler for mouseover
e = e || window.event;
var i, target = e.target || e.srcElement,
targetToolTip = target.nextElementSibling || nextSibling;//gets the next element in DOM (ie the tooltip)
//check if mouse is over a relevant element:
if (target.tagName.toLowerCase() !== 'a' || !target.className.match(/\bhd\b/))
{//nope? stop here, then
return e;
}
targetToolTip.style.display = 'block';//make visible
for (i=0;i<tooltips.length;i++)
{//closures are neat --> you have a reference to all tooltip elements from load scope
if (tooltips[i] !== targetToolTip)
{//not the one you need to see
tooltips[i].style.display = 'none';
}
}
};
for (i=0;i<tooltips.length;i++)
{
tooltips[i].style.display = 'none';
}
//add listener:
if (document.body.addEventListener)
{//IE > 9, chrome, safari, FF...
document.body.addEventListener('mouseover',mouseOver,false);
}
else
{//IE8
document.body.attachEvent('onmouseover',mouseOver);
}
}
Google JavaScript event delegation and closures if this code isn't clear, but that's just how I would tackle this kind of thing. IMO, it's fairly efficient (you could use the closure scope to keep track of the tooltip that's currently visible and not loop through all of them, too, that would be even better:
function load()
{
var i, tooltips = document.getElementsByClassName('toolTip'),
currentToolTip,//<-- reference currently visible
mouseOver = function(e)
{
e = e || window.event;
var i, target = e.target || e.srcElement,
targetToolTip = target.nextElementSibling || nextSibling;
if (target.tagName.toLowerCase() !== 'a' || !target.className.match(/\bhd\b/) || targetToolTip === currentToolTip)
{//add check for currently visible TT, if so, no further action required
return e;
}
if (currentToolTip !== undefined)
{
currentToolTip.style.display = 'none';//hide currently visible
}
targetToolTip.style.display = 'block';//make new visible
currentToolTip = targetToolTip;//keep reference for next event
};
for (i=0;i<tooltips.length;i++)
{
tooltips[i].style.display = 'none';
}
if (document.body.addEventListener)
{
document.body.addEventListener('mouseover',mouseOver,false);
}
else
{
document.body.attachEvent('onmouseover',mouseOver);
}
}
And you're there.
Edit:
To hide the tooltip on mouseout, you can either add a second listener directly:
function load()
{
var i, tooltips = document.getElementsByClassName('toolTip'),
currentToolTip,//<-- reference currently visible
mouseOver = function(e)
{
e = e || window.event;
var i, target = e.target || e.srcElement,
targetToolTip = target.nextElementSibling || nextSibling;
if (target.tagName.toLowerCase() !== 'a' || !target.className.match(/\bhd\b/) || targetToolTip === currentToolTip)
{//add check for currently visible TT, if so, no further action required
return e;
}
if (currentToolTip !== undefined)
{
currentToolTip.style.display = 'none';//hide currently visible
}
targetToolTip.style.display = 'block';//make new visible
currentToolTip = targetToolTip;//keep reference for next event
},
mouseOut = function(e)
{
e = e || window.event;
var movedTo = document.elementFromPoint(e.clientX,e.clientY);//check where the cursor is NOW
if (movedTo === curentToolTip || currentToolTip === undefined)
{//if cursor moved to tooltip, don't hide it, if nothing is visible, stop
return e;
}
currentTooltip.style.display = 'none';
currentTooltip = undefined;//no currentToolTip anymore
};
for (i=0;i<tooltips.length;i++)
{
tooltips[i].style.display = 'none';
}
if (document.body.addEventListener)
{
document.body.addEventListener('mouseover',mouseOver,false);
document.body.addEventListener('mouseout',mouseOut,false);
}
else
{
document.body.attachEvent('onmouseover',mouseOver);
document.body.attachEvent('onmouseout',mouseOut);
}
}
Note, this is completely untested. I'm not entirely sure if IE < 9 supports elementFromPoint (gets the DOM element that is rendered at certain coordinates), or even if the IE event object has the clientX and clientY properties, but I figure a quick google will tell you more, including how to get the coordinates and the element that is to be found under the cursor in old, crummy, ghastly IE8, but this should help you on your way. Of course, if you don't want the contents of the tooltip to be selectable, just change the mouseOut function to:
mouseOut = function(e)
{
e = e || window.event;
var target = e.target || e.srcElement;
if (currentToolTip)
{
currentToolTip.style.diplay = 'none';
currentToolTip = undefined;
}
};
No need to check if the mouseout was on the correct element, just check if there is a current tooltip, and hide it.
Try using classes to mark the tooltips:
<div id="toolTip1" class="toolTip">
<p>i can haz css tooltip</p>
<div id="tailShadow"></div>
<div id="tail1"></div>
<div id="tail2"></div>
</div>
And JQuery to toggle the visibility using the class as the selector:
$('.toolTip').attr('visibility', 'hidden')
Definitely clean up the non-unique Id's - this will cause you no end of troubles otherwise
Your problem is likely because you're using the same id for both the tooltips. This is invalid; an id should be unique -- only one element in a given page should have a specific ID.
If you need a shared identifier for multiple objects, use a class instead.
I built a tooltip with a border in pure js that doesn't use hover.
html
<div id="infoId" class='info' style="font-variant:small-caps;text-align:center;padding-top:10px;">
<span id="innerspanid">
</span>
</div>
</div>
<input id="startbtn" class="getstartedbtn" type="button" value="Start >" />
</div>
js
function getTextWidth(text, font) {
// re-use canvas object for better performance
const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
const context = canvas.getContext("2d");
context.font = font;
const metrics = context.measureText(text);
return metrics.width;
}
function getCssStyle(element, prop) {
return window.getComputedStyle(element, null).getPropertyValue(prop);
}
function getCanvasFontSize(el = document.body) {
const fontWeight = getCssStyle(el, 'font-weight') || 'normal';
const fontSize = getCssStyle(el, 'font-size') || '16px';
const fontFamily = getCssStyle(el, 'font-family') || 'Times New Roman';
return `${fontWeight} ${fontSize} ${fontFamily}`;
}
let arrowDimensionWidth = 20;
let arrowDimensionHeight = 20;
let tooltipTextHorizontalMargin = 50;
function openTooltip(text) {
let innerSpan = document.getElementById("innerspanid");
innerSpan.innerHTML = text;
let computedW = getTextWidth(text, getCanvasFontSize(innerSpan)) + tooltipTextHorizontalMargin;
let pointer = document.getElementById('pointer')
pointer.style.right = (((computedW / 2) - (arrowDimensionWidth / 2)) - (0)) + 'px';
let elem = document.getElementById('tooltipHost').parentNode.querySelector('div.info_container');
elem.style.left = ((tooltipHost.getBoundingClientRect().width - computedW) / 2) + "px";
elem.style.width = computedW + "px";
elem.style.display = 'block';
}
function buildTooltip() {
let elements = document.querySelectorAll('div.tooltip');
// Create a canvas element where the triangle will be drawn
let canvas = document.createElement('canvas');
canvas.width = arrowDimensionWidth; // arrow width
canvas.height = arrowDimensionHeight; // arrow height
let ctx = canvas.getContext('2d');
ctx.strokeStyle = 'darkred'; // Border color
ctx.fillStyle = 'white'; // background color
ctx.lineWidth = 1;
ctx.translate(-0.5, -0.5); // Move half pixel to make sharp lines
ctx.beginPath();
ctx.moveTo(1, canvas.height); // lower left corner
ctx.lineTo((canvas.width / 2), 1); // upper right corner
ctx.lineTo(canvas.width, canvas.height); // lower right corner
ctx.fill(); // fill the background
ctx.stroke(); // stroke it with border
ctx.fillRect(0, canvas.height - 0.5, canvas.width - 1, canvas.height + 2); //fix bottom row
// Create a div element where the triangle will be set as background
pointer = document.createElement('div');
pointer.id = "pointer"
pointer.style.width = canvas.width + 'px';
pointer.style.height = canvas.height + 'px';
pointer.innerHTML = ' ' // non breaking space
pointer.style.backgroundImage = 'url(' + canvas.toDataURL() + ')';
pointer.style.position = 'absolute';
pointer.style.top = '2px';
pointer.style.zIndex = '1'; // place it over the other elements
let idx;
let len;
for (idx = 0, len = elements.length; idx < len; ++idx) {
let elem = elements[idx];
let text = elem.querySelector('div.info');
let info = document.createElement('div');
text.parentNode.replaceChild(info, text);
info.className = 'info_container';
info.appendChild(pointer.cloneNode());
info.appendChild(text);
}
}
window.addEventListener('load', buildTooltip);
window.addEventListener('load', wireup);
function wireup() {
document.getElementById('startbtn').addEventListener('click', function (evt1) {
openTooltip("bad email no # sign");
return false;
});
}
css
div.tooltip {
position: relative;
display: inline-block;
}
div.tooltip > div.info {
display: none;
}
div.tooltip div.info_container {
position: absolute;
left: 0px;
width: 100px;
height: 70px;
display: none;
}
div.tooltip div.info {
position: absolute;
left: 0px;
text-align: left;
background-color: white;
font-size: 18px;
left: 1px;
right: 1px;
top: 20px;
bottom: 1px;
color: #000;
padding: 5px;
overflow: auto;
border: 1px solid darkred;
border-radius: 5px;
}
I want to do DRAG and REPLACE div in javascript. For Ex: I am having 2 Div's. If i drag the 2nd Div and place it on the 1st Div, automatically the 1st div should be replaced to the 2nd position. The code which i am having now is overlapping..
my aspx page..
<body>
<div id="container">
<div id="info">
Start drag process...</div>
<div id="square" style="position: relative; width: 60px; height: 60px; background: #990033;
border: 2px solid #3399CC;">
</div>
<div id="Div1" style="position: relative; width: 60px; height: 60px; background: #efe;
border: 2px solid #3399CC;">
</div>
<script type="text/javascript">
var square = DragHandler.attach(document.getElementById('square'));
var Div1 = DragHandler.attach(document.getElementById('Div1'));
</script>
</div>
my js file...
/**
*
* Crossbrowser Drag Handler
* http://www.webtoolkit.info/
*
**/
var DragHandler = {
// private property.
_oElem : null,
// public method. Attach drag handler to an element.
attach : function(oElem) {
oElem.onmousedown = DragHandler._dragBegin;
// callbacks
oElem.dragBegin = new Function();
oElem.drag = new Function();
oElem.dragEnd = new Function();
return oElem;
},
// private method. Begin drag process.
_dragBegin : function(e) {
var oElem = DragHandler._oElem = this;
if (isNaN(parseInt(oElem.style.left))) { oElem.style.left = '0px'; }
if (isNaN(parseInt(oElem.style.top))) { oElem.style.top = '0px'; }
var x = parseInt(oElem.style.left);
var y = parseInt(oElem.style.top);
e = e ? e : window.event;
oElem.mouseX = e.clientX;
oElem.mouseY = e.clientY;
oElem.dragBegin(oElem, x, y);
document.onmousemove = DragHandler._drag;
document.onmouseup = DragHandler._dragEnd;
return false;
},
// private method. Drag (move) element.
_drag : function(e) {
var oElem = DragHandler._oElem;
var x = parseInt(oElem.style.left);
var y = parseInt(oElem.style.top);
e = e ? e : window.event;
oElem.style.left = x + (e.clientX - oElem.mouseX) + 'px';
oElem.style.top = y + (e.clientY - oElem.mouseY) + 'px';
oElem.mouseX = e.clientX;
oElem.mouseY = e.clientY;
oElem.drag(oElem, x, y);
return false;
},
// private method. Stop drag process.
_dragEnd : function() {
var oElem = DragHandler._oElem;
var x = parseInt(oElem.style.left);
var y = parseInt(oElem.style.top);
oElem.dragEnd(oElem, x, y);
document.onmousemove = null;
document.onmouseup = null;
DragHandler._oElem = null;
}
}
How to do this...
Here is the recognition part:
for (var i = 0; i < document.getElementsByClassName("draggable").length; i++) {
var elem = document.getElementsByClassName("draggable")[i];
if (elem != oElem) {
if (oElem.offsetTop + parseInt(oElem.style.height) > elem.offsetTop
&& oElem.offsetTop < elem.offsetTop + parseInt(elem.style.height)) {
if (oElem.offsetLeft + parseInt(oElem.style.width) > elem.offsetLeft
&& oElem.offsetLeft < elem.offsetLeft + parseInt(elem.style.width)) {
alert("overlapping");
}
}
}
}
Your div's need to have a "draggable" class.
Demo: http://jsfiddle.net/DqJrV/
I'm looking for someone to explain how to drag and drop in javascript, I want a horizontal line with some customizable images in it.
I've had a look at the online tutorials for these but find them very hard to use.
I would recommend that you look into one of the Javascript Frameworks out there. We use prototype with scriptaculous.
You can look at a demo for Drag and Drop in Scriptaculous here. And you can run through a tutorial here.
Or look into any of the other frameworks such as JQuery or Dojo.
Here is my code as it is...I have used this page to get this far..
It currently moves everything into column one, I think it's something to do with the mouse.
print("<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Page</title>
<--
<style type="text/css">
<!--
.DragContainer, .OverDragContainer {
float: left;
margin: 3px;
width: 100px;
border: #669999 2px solid;
padding: 5px;
}
.DragBox, .OverDragBox, .DragDragBox, .miniDragBox {
border: #000 1px solid;
padding: 2px;
font-size: 10px;
margin-bottom: 5px;
width: 94px;
cursor: pointer;
font-family: verdana, tahoma, arial;
background-color: #eee;
}
.OverDragContainer {
background-color: #eee;
}
.OverDragBox, .DragDragBox {
background-color: #ffff99;
}
.DragDragBox {
filter: alpha(opacity=50);
background-color: #ff99cc;
}
legend {
font-weight: bold;
font-size: 12px;
color: #666699;
font-family: verdana, tahoma, arial;
}
fieldset {
padding: 3px;
}
.History {
font-size: 10px;
overflow: auto;
width: 100%;
font-family: verdana, tahoma, arial;
height: 82px;
}
#DragContainer8 {
border: #669999 1px solid;
padding: 5px 0 0 5px
width: 110px;
height: 40px;
}
.miniDragBox {
float: left;
margin: 0 5px 5px 0;
width: 20px;
height: 20px;
}
-->
</style>
<--script type="text/javascript">
// iMouseDown represents the current mouse button state: up or down
/*
lMouseState represents the previous mouse button state so that we can
check for button clicks and button releases:
if(iMouseDown && !lMouseState) // button just clicked!
if(!iMouseDown && lMouseState) // button just released!
*/
var mouseOffset = null;
var iMouseDown = false;
var lMouseState = false;
var dragObject = null;
// Demo 0 variables
var DragDrops = [];
var curTarget = null;
var lastTarget = null;
var dragHelper = null;
var tempDiv = null;
var rootParent = null;
var rootSibling = null;
Number.prototype.NaN0=function(){return isNaN(this)?0:this;}
function CreateDragContainer(){
/*
Create a new "Container Instance" so that items from one "Set" can not
be dragged into items from another "Set"
*/
var cDrag = DragDrops.length;
DragDrops[cDrag] = [];
/*
Each item passed to this function should be a "container". Store each
of these items in our current container
*/
for(var i=0; i<arguments.length; i++){
var cObj = arguments[i];
DragDrops[cDrag].push(cObj);
cObj.setAttribute('DropObj', cDrag);
/*
Every top level item in these containers should be draggable. Do this
by setting the DragObj attribute on each item and then later checking
this attribute in the mouseMove function
*/
for(var j=0; j<cObj.childNodes.length; j++){
// Firefox puts in lots of #text nodes...skip these
if(cObj.childNodes[j].nodeName=='#text') continue;
cObj.childNodes[j].setAttribute('DragObj', cDrag);
}
}
}
function getMouseOffset(target, ev){
ev = ev || window.event;
var docPos = getPosition(target);
var mousePos = mouseCoords(ev);
return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
}
function getPosition(e){
var left = 0;
var top = 0;
while (e.offsetParent){
left += e.offsetLeft;
top += e.offsetTop;
e = e.offsetParent;
}
left += e.offsetLeft;
top += e.offsetTop;
return {x:left, y:top};
}
function makeDraggable(item){
if(!item) return;
item.onmousedown = function(ev){
dragObject = this;
mouseOffset = getMouseOffset(this, ev);
return false;
}
}
function makeClickable(object){
object.onmousedown = function(){
dragObject = this;
}
}
function mouseCoords(ev){
if(ev.pageX || ev.pageY){
return {x:ev.pageX, y:ev.pageY};
}
return {
x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y:ev.clientY + document.body.scrollTop - document.body.clientTop
};
}
function mouseMove(ev){
ev = ev || window.event;
/*
We are setting target to whatever item the mouse is currently on
Firefox uses event.target here, MSIE uses event.srcElement
*/
var target = ev.target || ev.srcElement;
var mousePos = mouseCoords(ev);
// mouseOut event - fires if the item the mouse is on has changed
if(lastTarget && (target!==lastTarget)){
// reset the classname for the target element
var origClass = lastTarget.getAttribute('origClass');
if(origClass) lastTarget.className = origClass;
}
/*
dragObj is the grouping our item is in (set from the createDragContainer function).
if the item is not in a grouping we ignore it since it can't be dragged with this
script.
*/
var dragObj = target.getAttribute('DragObj');
// if the mouse was moved over an element that is draggable
if(dragObj!=null){
// mouseOver event - Change the item's class if necessary
if(target!=lastTarget){
var oClass = target.getAttribute('overClass');
if(oClass){
target.setAttribute('origClass', target.className);
target.className = oClass;
}
}
// if the user is just starting to drag the element
if(iMouseDown && !lMouseState){
// mouseDown target
curTarget = target;
// Record the mouse x and y offset for the element
rootParent = curTarget.parentNode;
rootSibling = curTarget.nextSibling;
mouseOffset = getMouseOffset(target, ev);
// We remove anything that is in our dragHelper DIV so we can put a new item in it.
for(var i=0; i<dragHelper.childNodes.length; i++) dragHelper.removeChild(dragHelper.childNodes[i]);
// Make a copy of the current item and put it in our drag helper.
dragHelper.appendChild(curTarget.cloneNode(true));
dragHelper.style.display = 'block';
// set the class on our helper DIV if necessary
var dragClass = curTarget.getAttribute('dragClass');
if(dragClass){
dragHelper.firstChild.className = dragClass;
}
// disable dragging from our helper DIV (it's already being dragged)
dragHelper.firstChild.removeAttribute('DragObj');
/*
Record the current position of all drag/drop targets related
to the element. We do this here so that we do not have to do
it on the general mouse move event which fires when the mouse
moves even 1 pixel. If we don't do this here the script
would run much slower.
*/
var dragConts = DragDrops[dragObj];
/*
first record the width/height of our drag item. Then hide it since
it is going to (potentially) be moved out of its parent.
*/
curTarget.setAttribute('startWidth', parseInt(curTarget.offsetWidth));
curTarget.setAttribute('startHeight', parseInt(curTarget.offsetHeight));
curTarget.style.display = 'none';
// loop through each possible drop container
for(var i=0; i<dragConts.length; i++){
with(dragConts[i]){
var pos = getPosition(dragConts[i]);
/*
save the width, height and position of each container.
Even though we are saving the width and height of each
container back to the container this is much faster because
we are saving the number and do not have to run through
any calculations again. Also, offsetHeight and offsetWidth
are both fairly slow. You would never normally notice any
performance hit from these two functions but our code is
going to be running hundreds of times each second so every
little bit helps!
Note that the biggest performance gain here, by far, comes
from not having to run through the getPosition function
hundreds of times.
*/
setAttribute('startWidth', parseInt(offsetWidth));
setAttribute('startHeight', parseInt(offsetHeight));
setAttribute('startLeft', pos.x);
setAttribute('startTop', pos.y);
}
// loop through each child element of each container
for(var j=0; j<dragConts[i].childNodes.length; j++){
with(dragConts[i].childNodes[j]){
if((nodeName=='#text') || (dragConts[i].childNodes[j]==curTarget)) continue;
var pos = getPosition(dragConts[i].childNodes[j]);
// save the width, height and position of each element
setAttribute('startWidth', parseInt(offsetWidth));
setAttribute('startHeight', parseInt(offsetHeight));
setAttribute('startLeft', pos.x);
setAttribute('startTop', pos.y);
}
}
}
}
}
// If we get in here we are dragging something
if(curTarget){
// move our helper div to wherever the mouse is (adjusted by mouseOffset)
dragHelper.style.top = mousePos.y - mouseOffset.y;
dragHelper.style.left = mousePos.x - mouseOffset.x;
var dragConts = DragDrops[curTarget.getAttribute('DragObj')];
var activeCont = null;
var xPos = mousePos.x - mouseOffset.x + (parseInt(curTarget.getAttribute('startWidth')) /2);
var yPos = mousePos.y - mouseOffset.y + (parseInt(curTarget.getAttribute('startHeight'))/2);
// check each drop container to see if our target object is "inside" the container
for(var i=0; i<dragConts.length; i++){
with(dragConts[i]){
if(((getAttribute('startLeft')) < xPos) &&
((getAttribute('startTop')) < yPos) &&
((getAttribute('startLeft') + getAttribute('startWidth')) > xPos) &&
((getAttribute('startTop') + getAttribute('startHeight')) > yPos)){
/*
our target is inside of our container so save the container into
the activeCont variable and then exit the loop since we no longer
need to check the rest of the containers
*/
activeCont = dragConts[i];
// exit the for loop
break;
}
}
}
// Our target object is in one of our containers. Check to see where our div belongs
if(activeCont){
// beforeNode will hold the first node AFTER where our div belongs
var beforeNode = null;
// loop through each child node (skipping text nodes).
for(var i=activeCont.childNodes.length-1; i>=0; i--){
with(activeCont.childNodes[i]){
if(nodeName=='#text') continue;
// if the current item is "After" the item being dragged
if(
curTarget != activeCont.childNodes[i] &&
((getAttribute('startLeft') + getAttribute('startWidth')) > xPos) &&
((getAttribute('startTop') + getAttribute('startHeight')) > yPos)){
beforeNode = activeCont.childNodes[i];
}
}
}
// the item being dragged belongs before another item
if(beforeNode){
if(beforeNode!=curTarget.nextSibling){
activeCont.insertBefore(curTarget, beforeNode);
}
// the item being dragged belongs at the end of the current container
} else {
if((curTarget.nextSibling) || (curTarget.parentNode!=activeCont)){
activeCont.appendChild(curTarget);
}
}
// make our drag item visible
if(curTarget.style.display!=''){
curTarget.style.display = '';
}
} else {
// our drag item is not in a container, so hide it.
if(curTarget.style.display!='none'){
curTarget.style.display = 'none';
}
}
}
// track the current mouse state so we can compare against it next time
lMouseState = iMouseDown;
// mouseMove target
lastTarget = target;
// track the current mouse state so we can compare against it next time
lMouseState = iMouseDown;
// this helps prevent items on the page from being highlighted while dragging
return false;
}
function mouseUp(ev){
if(curTarget){
// hide our helper object - it is no longer needed
dragHelper.style.display = 'none';
// if the drag item is invisible put it back where it was before moving it
if(curTarget.style.display == 'none'){
if(rootSibling){
rootParent.insertBefore(curTarget, rootSibling);
} else {
rootParent.appendChild(curTarget);
}
}
// make sure the drag item is visible
curTarget.style.display = '';
}
curTarget = null;
iMouseDown = false;
}
function mouseDown(){
iMouseDown = true;
if(lastTarget){
return false;
}
}
document.onmousemove = mouseMove;
document.onmousedown = mouseDown;
document.onmouseup = mouseUp;
window.onload = function(){
// Create our helper object that will show the item while dragging
dragHelper = document.createElement('DIV');
dragHelper.style.cssText = 'position:absolute;display:none;';
CreateDragContainer(
document.getElementById('DragContainer1'),
document.getElementById('DragContainer2'),
document.getElementById('DragContainer3')
);
document.body.appendChild(dragHelper);
}
</script><!--the mouse over and dragging class are defined on each item-->
</head>
<body>
<br/>
<div class="DragContainer" id="DragContainer1">
<div class="DragBox" id="Item1" overClass="OverDragBox" dragClass="DragDragBox">Item #1</div>
<div class="DragBox" id="Item2" overClass="OverDragBox" dragClass="DragDragBox">Item #2</div>
<div class="DragBox" id="Item3" overClass="OverDragBox" dragClass="DragDragBox">Item #3</div>
<div class="DragBox" id="Item4" overClass="OverDragBox" dragClass="DragDragBox">Item #4</div>
</div>
<div class="DragContainer" id="DragContainer2">
<div class="DragBox" id="Item5" overClass="OverDragBox" dragClass="DragDragBox">Item #5</div>
<div class="DragBox" id="Item6" overClass="OverDragBox" dragClass="DragDragBox">Item #6</div>
<div class="DragBox" id="Item7" overClass="OverDragBox" dragClass="DragDragBox">Item #7</div>
<div class="DragBox" id="Item8" overClass="OverDragBox" dragClass="DragDragBox">Item #8</div>
</div>
<div class="DragContainer" id="DragContainer3">
<div class="DragBox" id="Item9" overClass="OverDragBox" dragClass="DragDragBox">Item #9</div>
<div class="DragBox" id="Item10" overClass="OverDragBox" dragClass="DragDragBox">Item #10</div>
<div class="DragBox" id="Item11" overClass="OverDragBox" dragClass="DragDragBox">Item #11</div>
<div class="DragBox" id="Item12" overClass="OverDragBox" dragClass="DragDragBox">Item #12</div>
</div>
<br/>
</body>
</html>
");
Find 2x of:
dragHelper.style.top = mousePos.y - mouseOffset.y;
dragHelper.style.left = mousePos.x - mouseOffset.x;
change to:
dragHelper.style.top = mousePos.y - mouseOffset.y + 'px';
dragHelper.style.left = mousePos.x - mouseOffset.x + 'px';
Works on FF. 3.6
the answer is here jQuery drag-and-drop DIV selection with images and text
<script type="text/javascript" src="http://www.dynamicdrive.com/dynamicindex11/domdrag/dom-drag.js"></script>
<script type="text/javascript">
Drag.init(document.getElementById("exampleid")); //sets the id to look for to make object draggable
</script>