当我在页面上拖放元素时,元素变为“幻影”。基本上它有一些透明度值。
有没有办法让它成为opacity: 1;
?
答案 0 :(得分:29)
看起来无法完成。被拖动的元素被放入具有它自己的容器中,低于1,不透明度。这意味着虽然可以降低拖动元素的不透明度,但是不能使其高于封装元素的不透明度。
可能可以覆盖此类元素的默认浏览器设置,但由于在拖动过程中没有任何内容添加到DOM,因此最好是非常棘手。
答案 1 :(得分:7)
正如其他人所建议的那样,你需要某种机制:
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';
};
从附加元素开始:
new Drag(document.querySelector('.element'));
你可以完全控制可拖动元素的外观。在上面的例子中,我克隆了原始元素以将其用作句柄。您可以扩展Drag
函数以自定义句柄(例如,使用图像来表示可拖动元素)。
在你太兴奋之前,有几件事需要考虑:
<强>更新强>
我已经为WHATWG拖放机制https://github.com/gajus/pan编写了一个用于启用触摸的库。
答案 2 :(得分:3)
请参阅此工作fiddle
我有一个解决方案,可以在ghost的位置制作不透明的图像,并且在chrome中工作正常。但是它不能在FF中工作。我需要一些机构来帮助我在Firefox和其他浏览器中使用它。 脚步 1.我们将制作自己的鬼影并将其设置为拖动图像。
document.addEventListener("dragstart", function(e) {
var img = document.createElement("img");
img.src = "img/hackergotchi-simpler.png";
e.dataTransfer.setDragImage(img, 5000, 5000);//5000 will be out of the window
}, false);
2.我们将克隆图像并将其附加到DOM ondrag
var crt,dragX,dragY;
function drag(ev) {
crt = ev.target.cloneNode(true);
crt.style.position = "absolute";
document.body.appendChild(crt);
ev.dataTransfer.setData("text", ev.target.id);
}
3.然后我们将使用光标移动克隆
document.addEventListener("dragover", function(ev){
ev = ev || window.event;
dragX = ev.pageX; dragY = ev.pageY;
crt.style.left=dragX+"px";crt.style.top= dragY+"px";
console.log("X: "+dragX+" Y: "+dragY);
}, false);
4.最后,我们将使克隆可见性消失
document.addEventListener("dragend", function( event ) {crt.style.display='none';});
答案 3 :(得分:2)
如果您不是从网页外部(从操作系统)拖放元素,那么您可以通过实施自己的拖放操作轻松解决此问题。有很多纯javascript拖放的例子,它们可以在HTML5环境中完美运行,并且可以完全自定义。
回答:(用旧方式)
答案 4 :(得分:1)
对于那些对html5拖放操作感到失望的人(像我一样),这是一个基本的,原始的,跨浏览器,无缺陷且可完全自定义的解决方案:
html:
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="draggable"></div>
js:
var currentElement, currentDropzone, offsetX, offsetY;
function findZoneUnderPoint(x, y) {
var dropzones = preview.querySelectorAll(".dropzone");
for (var i = 0; i < dropzones.length; i++) {
var box = dropzones[i].getBoundingClientRect();
if (x > box.left && x < box.right && y > box.top && y < box.bottom) {
return dropzones[i];
}
}
}
function onMouseDown(event) {
currentElement = event.target.closest(".draggable");
if (currentElement) {
var box = currentElement.getBoundingClientRect();
offsetX = event.clientX - box.x;
offsetY = event.clientY - box.y;
currentElement.classList.add("drag");
currentElement.style.width = box.width.toFixed()+"px";
currentElement.style.height = box.height.toFixed()+"px";
currentElement.style.left = (event.clientX - offsetX) + "px";
currentElement.style.top = (event.clientY - offsetY) + "px";
currentElement.style.position = "fixed";
currentElement.style.zIndex = "999";
this.addEventListener("mousemove", onMouseMove);
this.addEventListener("mouseup", onMouseUp);
}
}
function onMouseMove(event) {
currentElement.style.left = (event.clientX - offsetX) + "px";
currentElement.style.top = (event.clientY - offsetY) + "px";
var dropzone = findZoneUnderPoint(event.clientX, event.clientY);
if (dropzone !== currentDropzone) {
if (dropzone) {
// -> drag enter zone
}
if (currentDropzone) {
// -> drag leave zone
}
currentDropzone = dropzone;
}
}
function onMouseUp(event) {
var dropzone = findZoneUnderPoint(event.clientX, event.clientY);
if (dropzone) {
// -> drag complete
} else {
// -> drag canceled
}
currentElement = null;
document.removeEventListener("mouseup", onMouseUp);
document.removeEventListener("mousemove", onMouseMove);
}
document.addEventListener("mousedown", onMouseDown);
注意:需要Element.closest()
polyfill来获得支持。
答案 5 :(得分:0)
如前所述,这是由浏览器处理的 - &gt;你不能改变这种行为,但如果你真的需要这种效果,试着在鼠标停止时寻找鼠标移动(简短:拖动),检查选择了哪个元素,并在鼠标光标后面立即创建一个副本。看起来像jQuery的理想工作;)
但如果你不需要它,我不会尝试更改浏览器的默认值,因为人们习惯了它,如果某些事情以另一种(未知)的方式表现,可能会感到困惑
答案 6 :(得分:0)
尽管这可能不是核心问题的真正解决方案,但我知道什么可能有用,至少我前一段时间在我的一个GWT项目中测试了它并且它有效,所以我想它可能在本机工作JS以及我没有代码示例:
不使用拖动功能,而是创建一个新元素,该元素等于在要拖动的元素的原始位置应该是dragget的元素。要拖动的原始元素现在应该是不可见的。实现恢复orignal元素的逻辑,并在不再按下鼠标时立即删除克隆。
使克隆元素保持在鼠标位置。删除克隆的事件还要检查鼠标是否被释放,而要拖动的元素位于可以拖动原始元素的区域上。
如果为true,请删除克隆并将原始元素移动到目标容器。
在CSS和JS中肯定还有很多调整工作要做,但这可能是一个淹没JS标准的技巧。
答案 7 :(得分:0)
我认为透明度不是来自网页内容,而是来自浏览器和操作系统。 如果要更改不透明度,则必须调整或破解浏览器和操作系统
答案 8 :(得分:0)
可以在“ chrome:// apps /”下的chrome(必须使用chrome)上查看2012年以后的工作示例。如果您想确切地知道他们是如何做到的,请打开dev tools(strg + shift + i
,因为左键用于自定义上下文菜单)并开始进行逆向工程(index.html中的7241行是一个很好的选择)。初始点)。
他们在dragstart
上克隆了拖动的元素,将其添加到某个顶级容器中,并将其定位到drag
上的光标上。为了避免将事件阻止到实际元素,他们使用pointer-events: none;
答案 9 :(得分:0)
请不要问我为什么会这样,但是如果您将不透明度设置为0.99999而不是1,那么它对我有效。 我真的很好奇为什么如果有人知道,请发表您的想法。
答案 10 :(得分:0)
在拖动开始时使用 event.dataTransfer.setDragImage(new Image(), 0, 0);
隐藏原始图像。 onDrag 获取重影图像,使用 event.pageX
, event.pageY
答案 11 :(得分:0)
自 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) {}
第 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';
}
第 2 步: 使用鼠标指针的 (x, y) 坐标更新拖动项目的位置。记得减去增量。
function onDrag(e) {
draggedItem.style.left = e.ClientX - dx;
draggedItem.style.top = e.ClientY - dy;
}
第 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;
}
这将使原来的拖动项目跟随半透明的拖动克隆,克服了不透明的影响。 onDrag 事件每 350 毫秒触发一次,并创建一个不错的可视化效果。
答案 12 :(得分:-4)
如果您使用的是JavaScript,则在处理dragStart事件的函数中包括将样式不透明度设置为1示例:
function dragStartHandler(e) {
this.style.opacity = '1.0';
}
答案 13 :(得分:-4)
建议,执行以下操作,现在为此我使用jQuery,尝试一下,然后说一些不会工作的东西,我们不是在这里给出答案,但这里指的是正确的方向。
function dragStartHandler(e) {
$("span.{CLASS}")addClass('overdrag');
}
然后你需要拿出来告诉它已经停止了拖动并掉到了位置,然后到了RemoveClass(&#39; overdrag&#39;);
这并不难,所以我认为你应该能够做到。我要感谢@DonaldHuckle,因为这不是我的解决方案。