我想在拖动元素时更改预览。 (参见setDragImage)
如果用户在拖动时按下 ctrl 或 Shift 键,就像使用另一个元素一样?
这是一个例子这里。此示例在您开始拖动操作时显示图像。然而,如果你想即时改变它,那就相当具有挑战性了!
这可能吗?
我认为仅使用本机 API 是可能的,因为 setDragImage 文档以 “当发生拖动时,...” 开头。 在其他事件上调用 setDragImage 不会出现错误,但似乎不起作用。
但是可以使用您自己的精灵来实现动态拖拽图像。
const areas=[
{
dom:document.querySelector('.zone-red'),
headSprite:'🐰',
bodySprite:'🐇',
},
{
dom:document.querySelector('.zone-blue'),
headSprite:'🐭',
bodySprite:'🐀',
}
];
const traveller={
current:0,
dom: document.querySelector('.traveller')
};
const sprite=document.querySelector('.drag-image');
const blank=document.querySelector('.drag-blank');
const mouseMove=evt=>{
sprite.style.left=(evt.pageX-15)+'px';
sprite.style.top=(evt.pageY-15)+'px';
};
traveller.dom.draggable = true;
traveller.dom.ondragstart = evt => {
evt.dataTransfer.setDragImage(blank, 0, 0);
sprite.innerHTML=areas[traveller.current].headSprite;
sprite.style.display='block';
mouseMove(evt);
};
traveller.dom.ondragend = evt => {
sprite.style.display='none';
};
areas.forEach((area,id)=>{
area.dom.ondragover = evt => {
evt.preventDefault();
mouseMove(evt);
sprite.innerHTML=areas[id].headSprite;
};
area.dom.ondrop = evt => {
evt.preventDefault();
evt.stopPropagation();
traveller.current=id;
traveller.dom.innerHTML=areas[id].bodySprite;
area.dom.appendChild(traveller.dom);
};
});
.world{
display:flex;
}
.zone{
width:100px;
height:100px;
border:solid 1px;
}
.zone-blue{
color:#00f;
background-color:#eef;
}
.zone-red{
color:#f00;
background-color:#fee;
}
.traveller{
cursor:default;
}
.drag-image{
position:fixed;
pointer-events:none;
}
.drag-blank{
width:'1px';
height:'1px';
opacity:0;
}
<div class="world">
<div class="zone zone-red">
Rabbits
<div class="traveller">
🐇
</div>
</div>
<div class="zone zone-blue">
Rats
</div>
</div>
<div class="drag-image"></div>
<div class="drag-blank"></div>
PS:当然应该进行优化,例如仅在精灵改变区域时才修改精灵。