我将 Angular 与angular-drag-and-drop-lists指令一起使用。它使用 HTML5 API 来实现拖放。我注意到,当将一个元素拖到浏览器地址栏上时,地址会被元素的数据重写,并且驱动程序会离开我的站点。有没有办法防止元素被拖到地址栏或限制它的拖动区域?
2 回答
这是特定于操作系统/浏览器的,并且级别低于您的代码允许的级别。所以你将无法从你的代码中做任何事情。
如果您控制dragstart 事件,您可以定义拖动数据存储的effectAllowed。这将定义您的系统如何处理您拖动的元素。您有不同的选择,它们的行为会根据您放置它们的位置和内容而有所不同。这也将影响它如何影响地址栏中的下降。
以下是您可以设置的一些行为示例。例如,在 Chrome 上,当您将效果设置为'none'时,将元素拖动到地址栏不会做任何事情,但使用'copy'它将搜索类型为'text/plain' 的文本。具有“复制” 效果的图像将在浏览器中打开。
其他地方的行为也会有所不同。例如,如果您在查找器中拖动元素(在 Mac OS 上),它将创建图像或内容为'text/plain'的文本文件。在 Microsoft Word 中,将在页面中插入图像,或者将插入带有格式的“text/html” 。
像这样:
document.getElementById('noneImg').addEventListener('dragstart', setEffect)
document.getElementById('copyImg').addEventListener('dragstart', setEffect)
document.getElementById('linkImg').addEventListener('dragstart', setEffect)
document.getElementById('noneText').addEventListener('dragstart', setEffect)
document.getElementById('copyText').addEventListener('dragstart', setEffect)
document.getElementById('linkText').addEventListener('dragstart', setEffect)
function setEffect(e) {
if(e.target.tagName === 'DIV'){
e.dataTransfer.setData('text/plain', 'test');
e.dataTransfer.setData('text/html', '<b>bold</b>');
}
e.dataTransfer.effectAllowed = e.target.className;
}
img {
width: 80px;
height: 80px;
}
<img id="noneImg" class="none" src="http://koncha.890m.com/wp-content/uploads/2016/06/2.jpg" />
<img id="copyImg" class="copy" src="http://koncha.890m.com/wp-content/uploads/2016/06/2.jpg" />
<img id="linkImg" class="link" src="http://koncha.890m.com/wp-content/uploads/2016/06/2.jpg" />
<div draggable="true" id="noneText" class="none">effect none</div>
<div draggable="true" id="copyText" class="copy">effect copy</div>
<div draggable="true" id="linkText" class="link">effect link</div>
请参阅https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/effectAllowed
如果您不控制dragstart 事件,那么您无能为力。这意味着从您的操作系统或其他窗口拖动的所有内容。
编辑:
为了澄清一点,drop 的行为方式取决于 3 件事:
- 拖动数据存储的内容,
- 效果允许
- 以及进行删除的应用程序
您需要将每个浏览器视为不同的应用程序,因此行为会因浏览器而异,并且可能会因操作系统和浏览器版本而异。例如,在我可用的浏览器上,在 Chrome 上,effectAllowed none不会做任何事情。但在 Firefox 上它会触发下降。
此外,拖动数据存储是一组复杂的数据,您可以在其中拥有多种数据类型,并且根据应用程序将使用不同的数据类型。因此,例如,如果您有一个“文本”数据类型,它会将文本数据类型的内容放在地址栏中(在 Chrome 上,这发生在“复制”效果允许,但不是“链接”。使用 Firefox将丢弃它,无论定义了 effectAllowed)。
调整行为的一种方法是使用clearData。这将清除拖动数据存储。完成此操作后,您可以根据需要定义自己的类型。例如,使用自定义类型,您可以清除所有其他行为并仅在页面中保留您需要的行为。
例如,在这里,您可以放置,根据哪个放置,您可以访问不同的数据,并且没有与其他应用程序的交互。
document.getElementById('noneImg').addEventListener('dragstart', setEffect)
document.getElementById('copyImg').addEventListener('dragstart', setEffect)
document.getElementById('linkImg').addEventListener('dragstart', setEffect)
document.getElementById('noneText').addEventListener('dragstart', setEffect)
document.getElementById('copyText').addEventListener('dragstart', setEffect)
document.getElementById('linkText').addEventListener('dragstart', setEffect)
function setEffect(e) {
e.dataTransfer.clearData();
e.dataTransfer.setData('custom', 'custom data');
e.dataTransfer.setData('custom2', 'other custom data');
e.dataTransfer.effectAllowed = e.target.className;
}
document.getElementById('drop').addEventListener('dragover', (e) => {
e.preventDefault();
e.target.style.backgroundColor = 'blue';
});
document.getElementById('drop').addEventListener('dragleave', (e) => {
e.preventDefault();
e.target.style.backgroundColor = "";
});
document.getElementById('drop').addEventListener('drop', (e) => {
console.log(e.dataTransfer.getData('custom'));
e.target.style.backgroundColor = "";
e.preventDefault();
});
document.getElementById('drop2').addEventListener('dragover', (e) => {
e.preventDefault();
e.target.style.backgroundColor = 'blue';
});
document.getElementById('drop2').addEventListener('dragleave', (e) => {
e.preventDefault();
e.target.style.backgroundColor = "";
})
document.getElementById('drop2').addEventListener('drop', (e) => {
console.log(e.dataTransfer.getData('custom2'));
e.target.style.backgroundColor = "";
e.preventDefault();
});
img {
width: 80px;
height: 80px;
}
#drop,
#drop2,
#drop3 {
width: 200px;
height: 200px;
border: solid 1px black;
float: left;
}
<img id="noneImg" class="none" src="http://koncha.890m.com/wp-content/uploads/2016/06/2.jpg" />
<img id="copyImg" class="copy" src="http://koncha.890m.com/wp-content/uploads/2016/06/2.jpg" />
<img id="linkImg" class="link" src="http://koncha.890m.com/wp-content/uploads/2016/06/2.jpg" />
<div draggable="true" id="noneText" class="none">effect none</div>
<div draggable="true" id="copyText" class="copy">effect copy</div>
<div draggable="true" id="linkText" class="link">effect link</div>
<div id="drop">
</div>
<div id="drop2">
</div>