When I drag and drop an element on my page the element becomes \"ghosted\". Basically it gets some transparency value.
Is there some way to make it opacity: 1;
It looks like it can't be done. The dragged element is put into container that has it's own, lower than 1, opacity. This means that while you can lower the opacity of the dragged element you can't get it higher than the opacity of the encapsulating element.
It might be possible to override default browser settings for such element, but since nothing is added to DOM during the drag it would be very tricky at best.
Please don't ask me why this works, but if you set the opacity to 0.99999 instead of 1 it works for me. I'm really curious to why so if anyone knows, please post your thoughts.
I think the transparency doesn't come from the web contents but from the browser and OS. If you want to change the opacity, you must to tweak or hack the browser and OS
altough this is propably not the real solution of the core problem, I have an idea what might work, at least I tested this in one of my GWT project some time ago and it worked, so I guess it might work in native JS as well altough I have no code example:
Instead of using the dragging function, create a new element which equals the element that should be dragget at the original position of the element to be dragged. The original Element to be dragged should be made invisible now. Implement a logic that restores the orignal element and removes the clone as soon as the mouse isn't pressed anymore.
Make the clone Element stick to the mouse's position. The event that removes the clone has also to check if the mouse is released while the element to drag is positioned over an area where the original ement could be dragged to.
If true, remove the clone and move the original element to the target container.
There is definitely a lot of adjustment work to do in CSS and JS as well, but It might be a trick to overwhelm the JS standard.
If you are using JavaScript then in the function which handles the dragStart event include set the style opacity to 1 example:
function dragStartHandler(e) {
this.style.opacity = '1.0';
}
As others have suggested, you will need some sort of mechanism that will:
drag
event to position the clone element.In practise, looks like this:
function Drag (subject) {
var dative = this,
handle,
dragClickOffsetX,
dragClickOffsetY,
lastDragX,
lastDragY;
subject.draggable = true;
dative.styleHandle(subject);
subject.addEventListener('dragstart', function (e) {
handle = dative.makeHandle(subject);
dragClickOffsetX = e.layerX;
dragClickOffsetY = e.layerY;
this.style.opacity = 0;
});
subject.addEventListener('drag', function (e) {
var useX = e.x,
useY = e.y;
// Odd glitch
if (useX === 0 && useY === 0) {
useX = lastDragX;
useY = lastDragY;
}
if (useX === lastDragX && useY === lastDragY) {
return;
}
dative.translate(useX - dragClickOffsetX, useY - dragClickOffsetY, handle, subject);
lastDragX = useX;
lastDragY = useY;
});
subject.addEventListener('dragend', function (e) {
this.style.opacity = 1;
handle.parentNode.removeChild(handle);
});
};
/**
* Prevent the text contents of the handle element from being selected.
*/
Drag.prototype.styleHandle = function (node) {
node.style['userSelect'] = 'none';
};
/**
* @param {HTMLElement} subject
* @return {HTMLElement}
*/
Drag.prototype.makeHandle = function (subject) {
return this.makeClone(subject);
};
/**
* Clone node.
*
* @param {HTMLElement} node
* @return {HTMLElement}
*/
Drag.prototype.makeClone = function (node) {
var clone;
clone = node.cloneNode(true);
this.styleClone(clone, node.offsetWidth, node.offsetHeight);
node.parentNode.insertBefore(clone, node);
return clone;
};
/**
* Make clone width and height static.
* Take clone out of the element flow.
*
* @param {HTMLElement} node
* @param {Number} width
* @param {Nubmer} height
*/
Drag.prototype.styleClone = function (node, width, height) {
node.style.position = 'fixed';
node.style.zIndex = 9999;
node.style.width = width + 'px';
node.style.height = height + 'px';
node.style.left = '-9999px';
node.style.margin = 0;
node.style.padding = 0;
};
/**
* Used to position the handle element.
*
* @param {Number} x
* @param {Number} y
* @param {HTMLElement} handle
* @parma {HTMLElement} subject
*/
Drag.prototype.translate = function (x, y, handle, subject) {
handle.style.left = x + 'px';
handle.style.top = y + 'px';
};
Start with attaching an element:
new Drag(document.querySelector('.element'));
And you have a working drag and drop with full control over the looks of the draggable element. In the above example, I clone the original element to use it as the handle. You can extend the Drag
function to customise the handle (e.g. use image to represent the draggable element).
Before you get too excited, there are couple of things to consider:
Update:
I have written a library for touch enabled implementation of WHATWG drag and drop mechanism, https://github.com/gajus/pan.