Joh*_*gen 42 javascript html5 css3
当我在页面上拖放元素时,元素变为"幻影".基本上它有一些透明度的价值.
有没有办法让它成功opacity: 1;?
c2h*_*5oh 32
看起来它无法完成.被拖动的元素被放入具有它自己的容器中,低于1,不透明度.这意味着虽然可以降低拖动元素的不透明度,但是无法使其高于封装元素的不透明度.
有可能覆盖此类元素的默认浏览器设置,但由于在拖动过程中没有任何内容添加到DOM,因此最多也会非常棘手.
正如其他人所建议的那样,您将需要某种机制:
drag事件以定位克隆元素.在实践中,看起来像这样:
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';
};
Run Code Online (Sandbox Code Playgroud)
从附加元素开始:
new Drag(document.querySelector('.element'));
Run Code Online (Sandbox Code Playgroud)
而且你可以完全控制可拖动元素的外观.在上面的例子中,我克隆了原始元素以将其用作句柄.您可以扩展该Drag功能以自定义句柄(例如,使用图像来表示可拖动元素).
在你太兴奋之前,有几件事需要考虑:
更新:
我已经编写了一个库,用于启用触摸功能的WHATWG拖放机制,https://github.com/gajus/pan.
截至 2021 年,您无需克隆该元素。浏览器创建一个半透明的克隆,在拖动事件上跟随鼠标指针。同时,原始拖动的项目保持不变,没有任何变化。
如果您希望显示被拖动的原始元素以跟随鼠标指针,那么这里有一个技巧。
设置:
<!- HTML Code Sample ->
<div draggable="true"
ondragstart="onDragStart(event)" ondrag="onDrag(event)"
ondragend="onDragEnd(event)">
<!- JS Code Sample ->
var dx = 0, dy = 0, draggedItem = undefined;
function onDragStart(e) {}
function onDrag(e) {}
function onDragEnd(e) {}
Run Code Online (Sandbox Code Playgroud)
步骤 1: 将拖动项目的 (x, y) 坐标与鼠标指针坐标之间的差值保存为 delta。
function onDragStart(e) {
draggedItem = e.target;
dx = e.clientX - draggedItem.getBoundingClientRect().x;
dy = e.clientY - draggedItem.getBoundingClientRect().y;
draggedItem.style.position = 'absolute';
}
Run Code Online (Sandbox Code Playgroud)
步骤 2: 用鼠标指针的 (x, y) 坐标更新拖动项目的位置。记住减去增量。
function onDrag(e) {
draggedItem.style.left = e.ClientX - dx;
draggedItem.style.top = e.ClientY - dy;
}
Run Code Online (Sandbox Code Playgroud)
步骤 3: 取决于是否保留拖动项目的新位置或运行一些自定义逻辑。
function onDragEnd(e) {
if('retain new position ???'){
draggedItem.style.left = e.ClientX - dx;
draggedItem.style.top = e.ClientY - dy;
} else {
draggedItem.style.position = 'static';
// Add your custom logic to handle drag completion
}
// Clear temporary data
draggedItem = undefined;
dx = dy = 0;
}
Run Code Online (Sandbox Code Playgroud)
这将使原始拖动的项目跟随半透明拖动的克隆,从而克服了不透明度的影响。onDrag 事件每 350 毫秒触发一次,并创建一个不错的可视化效果。