【发布时间】:2015-12-18 11:37:36
【问题描述】:
我正在使用带有 angular-drag-and-drop-lists 指令的 Angular。它使用 HTML5 API 来实现拖放。我注意到,当将一个元素拖到浏览器地址栏上时,地址会被元素的数据重写,并且驱动程序会离开我的站点。有没有办法防止元素被拖到地址栏上或限制它的拖拽区域?
【问题讨论】:
标签: javascript angularjs html drag-and-drop html5-draggable
我正在使用带有 angular-drag-and-drop-lists 指令的 Angular。它使用 HTML5 API 来实现拖放。我注意到,当将一个元素拖到浏览器地址栏上时,地址会被元素的数据重写,并且驱动程序会离开我的站点。有没有办法防止元素被拖到地址栏上或限制它的拖拽区域?
【问题讨论】:
标签: javascript angularjs html drag-and-drop html5-draggable
这是特定于操作系统/浏览器的,并且级别低于您的代码允许的级别。所以你将无法从你的代码中做任何事情。
【讨论】:
如果您控制 dragstart 事件,您可以定义拖动数据存储的 effectAllowed。这将定义您的系统如何处理您拖动的元素。您有不同的选择,它们的行为会根据您放置它们的位置和内容而有所不同。这也会影响它如何影响地址栏中的拖放。
以下是您可以设置的一些行为示例。例如,在 Chrome 上,当您将效果设置为 'none' 时,将元素拖到地址栏不会执行任何操作,但使用 'copy'将搜索类型为 'text/plain' 的文本。带有 'copy' effectAllowed 的图像将在浏览器中打开。
其他地方的行为也会有所不同。例如,如果您在查找器中拖动元素(在 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 上它会触发一个 drop。
此外,拖动数据存储是一组复杂的数据,您可以在其中拥有多种数据类型,并且根据应用程序的不同,将使用不同的数据类型。因此,例如,如果您有一个“文本”数据类型,它会将文本数据类型的内容放在地址栏中(在 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>
【讨论】:
link 做得很完美。谢谢!